Reputation: 2341
type X = { aa: number; bb: string };
const get = <Key extends keyof X>(key: Key) => {
type T<Value extends X[Key]> = Value;
const a: T<any>;
/**
* Type 'string' does not satisfy the constraint 'X[Key]'.
Type 'string' is not assignable to type 'never'.
*/
const b: T<string>;
};
From my opinion, Value
should be of type string|number
, how it was calculated as never
by typescript
Upvotes: 0
Views: 160
Reputation: 1444
You wrote the get
function in such a way that when it calls, it can be given any type as a generic parameter, that is the subset of X
keys.
So the condition in T<Value extends X[Key]>
is ambiguous for typescript.
For example :
get<"aa">("aa")
results T<Value extends number>
get<"bb">("bb")
results T<Value extends string>
get<"aa" | "bb">("bb")
results T<Value extends string | number>
Thus when you do const b: T<string>;
, it does not know what the condition exactly is and it says:
Type 'string' does not satisfy the constraint 'X[Key]'
I don't know the purpose of the function in your project, but I think it can be rewritten in this way using conditional types:
type X = { aa: number; bb: string };
const get = () => {
type MyType<Value, K extends keyof X = keyof X> = Value extends X[K] ? Value : never;
const a: MyType<any> = true; //------> any other value can be assigned
const b: MyType<string> = "Test"; // -------> it is string type
};
I hope it helps you.
By the way you can read more about conditional types here.
Upvotes: 1