I don't know what exactly to call this problem but this is my case.
I want defaultValue
to automatically get type based on id
value.
type User = {
name: string;
age: number;
};
type PropConfig<T, K extends keyof T> = {
id: K;
label: string;
defaultValue: T[K];
};
const config: PropConfig<User, 'age'> = {
id: 'age',
label: 'Age',
defaultValue: 18,
};
This is what I want:
type PropConfig<T, K = keyof T> = {
id: K;
label: string;
defaultValue: T[K]; // Error here
};
const config: PropConfig<User> = {
id: 'age',
label: 'Age',
defaultValue: 18,
};
Can someone help me?
TypeScript doesn't have partial type argument inference as proposed in ms/TS#26242 so there's no way to specify T
while having the compiler infer K
, at least not without workarounds involving curried helper functions or dummy parameters (see Typescript: infer type of generic after optional first generic for more info).
Luckily, I don't think you want PropConfig
to be generic in K
. Instead, you want PropConfig<T>
to be a union of the possible types for each K
in keyof T
. That is, you want to distribute the type across unions in keyof T
. There are a number of ways to do that, but the one I usually do is to make what's called a distributive object type , as coined in ms/TS#47109 . It looks like this:
type PropConfig<T> = { [K in keyof T]-?: {
id: K;
label: string;
defaultValue: T[K];
} }[keyof T]
I immediately index into a mapped type , producing the following for PropConfig<User>
:
type PropConfigUser = PropConfig<User>;
/* type PropConfigUser = {
id: "name";
label: string;
defaultValue: string;
} | {
id: "age";
label: string;
defaultValue: number;
} */
which is the type you want:
const config: PropConfig<User> = {
id: 'age',
label: 'Age',
defaultValue: 18,
};
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.