You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Why do you expect this behaviour? What's your reasoning and thought process?
The return argument of your function is just params, and params is just typed T1. This type argument is inferred from the provided parameter, and you provide ["a"] as the value. This looks just fine.
Why do you expect this behaviour? What's your reasoning and thought process?
The return argument of your function is just params, and params is just typed T1. This type argument is inferred from the provided parameter, and you provide ["a"] as the value. This looks just fine.
I want result is ['a'], will be used to obtain the value of data
Your second argument gets widened to string[] in the first inference pass. That's gathered as the inference candidate, it fails the constraint check so the constraint gets selected as the inference result.
TS doesn't recognize that your T1 has a tuple-like constraint (getBaseConstraintOfType just returns unknown). I suspect that's because it's a recursive type without a direct hint that it returns a tuple type. When u wrapped the second union member with [...T] you essentially gave it that hint and that's why it works.
Your second argument gets widened to string[] in the first inference pass. That's gathered as the inference candidate, it fails the constraint check so the constraint gets selected as the inference result.
TS doesn't recognize that your T1 has a tuple-like constraint (getBaseConstraintOfType just returns unknown). I suspect that's because it's a recursive type without a direct hint that it returns a tuple type. When u wrapped the second union member with [...T] you essentially gave it that hint and that's why it works.
Since this hasn't been said explicitly yet: this isn't a bug in TypeScript so this isn't really the right place for this discussion. Stack Overflow or the TS Discord would be more appropriate venues. 叶枫 (@crazyair), could you please close the issue to free up the TS team's time? Once it's closed I imagine anyone who's still interested could continue discussing here.
To make it work you need to be in some inference context and that means that you need a function call to make it work (and annotate its type params as const). This kinda should work:
but it doesn't because TS doesn't currently handle context-sensitive functions in reverse-mapped types that well. It's something I want to improve in #54029
Activity
MartinJohns commentedon Aug 1, 2023
Why do you expect this behaviour? What's your reasoning and thought process?
The return argument of your function is just
params, andparamsis just typedT1. This type argument is inferred from the provided parameter, and you provide["a"]as the value. This looks just fine.crazyair commentedon Aug 1, 2023
I want result is
['a'], will be used to obtain the value of datacrazyair commentedon Aug 1, 2023
func({ a: { a1: string }, b: number }, ['a']);input
['a', 'a1']resultstringinput
bresultnumbercrazyair commentedon Aug 1, 2023
export type DeepNamePath<T = any> = T extends Record<string, any> ? { - [P in keyof T]: [P] | DeepNamePath<T[P]>; + [P in keyof T]: [P] | [...DeepNamePath<T[P]>]; }[keyof T] : never;If I write this way, I can get
['a'], but it requiresDeepNamePathto return an arrayAndarist commentedon Aug 1, 2023
Your second argument gets widened to
string[]in the first inference pass. That's gathered as the inference candidate, it fails the constraint check so the constraint gets selected as the inference result.TS doesn't recognize that your
T1has a tuple-like constraint (getBaseConstraintOfTypejust returnsunknown). I suspect that's because it's a recursive type without a direct hint that it returns a tuple type. When u wrapped the second union member with[...T]you essentially gave it that hint and that's why it works.For similar reasons this one work:
This one doesn't really recognize the tuple-like base constraint but it introduces a
constcontext and has a similar effect on the overall thing.crazyair commentedon Aug 1, 2023
I thought of const, but I couldn't write it at the time.
const T1 extends ddd<T> = ddd<T>jcalz commentedon Aug 1, 2023
Since this hasn't been said explicitly yet: this isn't a bug in TypeScript so this isn't really the right place for this discussion. Stack Overflow or the TS Discord would be more appropriate venues. 叶枫 (@crazyair), could you please close the issue to free up the TS team's time? Once it's closed I imagine anyone who's still interested could continue discussing here.
edit: Thanks! 🙏
crazyair commentedon Aug 2, 2023
Mateusz Burzyński (@Andarist)
valuetype isreadonly ["a"] | readonly ["b"], i wantreadonly ["a"]crazyair commentedon Aug 2, 2023
'const' modifier can only appear on a type parameter of a function, method or classts(1277)Andarist commentedon Aug 2, 2023
To make it work you need to be in some inference context and that means that you need a function call to make it work (and annotate its type params as
const). This kinda should work:but it doesn't because TS doesn't currently handle context-sensitive functions in reverse-mapped types that well. It's something I want to improve in #54029
crazyair commentedon Aug 2, 2023
I need
crazyair commentedon Aug 2, 2023
If
listthere are 2 pieces of data(parameter) value: "a" | "b"If
listthere are 1 pieces of data(parameter) value: "a"