[英]How to define a type inside a generic interface for a property inside this generic type
Example:例子:
export interface Column<T> {
field: string;
columnFormatter?: (props: {
value: any/** field type inside T**/; data: T; node: any
}) => void;
}
field is the name of the property inside type T, how can I say that the value is of that type? field 是类型 T 内的属性的名称,我怎么能说该值是该类型?
export interface IPurchase {
id: string;
name: string;
purchaseDate: Date;
}
let doSomethingWithMyDate: (myDate: Date) => (true);
const columns: Array<Column<IPurchase>> = [
{
field: "purchaseDate", /* "purchaseDate" must be inside IPurchase */
columnFormatter: ({ value /* must identify that this is a Date */ }) =>
doSomethingWithMyDate(value)
}];
In order to represent the correlation between the field
property and the type of the value
property of the props
parameter to columnFormatter
, you need Column<T>
to be a union type with one member for every key of T
.为了表示field
属性与columnFormatter
的props
参数的value
属性类型之间的相关性,您需要Column<T>
是一个联合类型,其中T
的每个键都有一个成员。 For example, given your IPurchase
example, you need Column<IPurchase>
to be例如,给定您的IPurchase
示例,您需要Column<IPurchase>
为
type ColumnIPurchase = {
field: "id";
columnFormatter?: ((props: {
value: string;
data: IPurchase;
node: any;
}) => void);
} | {
field: "name";
columnFormatter?: ((props: {
value: string;
data: IPurchase;
node: any;
}) => void)
} | {
field: "purchaseDate";
columnFormatter?: ((props: {
value: Date;
data: IPurchase;
node: any;
}) => void);
}
This will behave as desired:这将按需要运行:
const columns: Array<Column<IPurchase>> = [
{
field: "purchaseDate",
columnFormatter: ({ value }) => doSomethingWithMyDate(value)
},
{
field: "name",
columnFormatter: ({ value }) => doSomethingWithMyDate(value) // error!
// string isn't a Date ----------------------------> ~~~~~
}
];
So that's what we want... how can we write Column<T>
to do it?所以这就是我们想要的......我们如何编写Column<T>
来做到这一点?
Here's one way:这是一种方法:
type Column<T> = { [K in keyof T]-?: {
field: K;
columnFormatter?: (props: { value: T[K]; data: T; node: any }) => void;
} }[keyof T]
The general form of this type, {[K in keyof T]-?: F<K>}[keyof T]
, is known as a distributive object type , as coined in microsoft/TypeScript#47109 ;这种类型的一般形式{[K in keyof T]-?: F<K>}[keyof T]
被称为分布式对象类型,如microsoft/TypeScript#47109中所创造的; we are making a mapped type over the keys in keyof T
and then immediately index into it with keyof T
so as to get a union of F<K>
for every key K
in keyof T
.我们在keyof T
中的键上创建一个映射类型,然后立即使用keyof T
对其进行索引,以便为 keyof T 中的每个键K
获得F<K>
的并keyof T
。
In particular here we are computing { field: K; columnFormatter?: (props: { value: T[K]; data: T; node: any }) => void; }
特别是在这里我们正在计算{ field: K; columnFormatter?: (props: { value: T[K]; data: T; node: any }) => void; }
{ field: K; columnFormatter?: (props: { value: T[K]; data: T; node: any }) => void; }
{ field: K; columnFormatter?: (props: { value: T[K]; data: T; node: any }) => void; }
where K
is the type of the key, and T[K]
is the type of the property value corresponding to that key.其中{ field: K; columnFormatter?: (props: { value: T[K]; data: T; node: any }) => void; }
是键的类型, T[K]
K
该键对应的属性值的类型。
And you can verify that Column<IPurchase>
evaluates to exactly the desired type.您可以验证Column<IPurchase>
的计算结果完全符合所需的类型。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.