[英]Typescript - Dynamic Generics Type
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.我希望
defaultValue
根据id
值自动获取类型。
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). TypeScript 没有ms/TS#26242中建议的部分类型参数推断,因此在让编译器推断
K
时无法指定T
,至少在没有涉及柯里化辅助函数或虚拟参数的解决方法的情况下(参见Typescript:推断类型可选的第一个泛型之后的泛型以获取更多信息)。
Luckily, I don't think you want PropConfig
to be generic in K
.幸运的是,我不认为您希望
PropConfig
在K
中是通用的。 Instead, you want PropConfig<T>
to be a union of the possible types for each K
in keyof T
.相反,您希望
PropConfig<T>
成为keyof T
中每个K
的可能类型的联合。 That is, you want to distribute the type across unions in keyof T
.也就是说,您希望在
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 .有很多方法可以做到这一点,但我通常做的一种是创建所谓的分布式对象类型,正如在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>
:我立即索引到映射类型,为
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,
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.