如何为此泛型类型中的属性定义泛型接口内的类型



示例:

export interface Column<T> {
field: string;
columnFormatter?: (props: {
value: any/** field type inside T**/; data: T; node: any
}) => void;
}

字段是类型 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)
}];

为了表示field属性与要columnFormatterprops参数的value属性类型之间的相关性,您需要Column<T>为联合类型,每个键都有一个成员T。 例如,给定您的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);
}

这将按预期运行:

const columns: Array<Column<IPurchase>> = [
{
field: "purchaseDate",
columnFormatter: ({ value }) => doSomethingWithMyDate(value)
},
{
field: "name",
columnFormatter: ({ value }) => doSomethingWithMyDate(value) // error!
//  string isn't a Date ----------------------------> ~~~~~ 
}
];

这就是我们想要的...我们怎么能写Column<T>来做到这一点?


这是一种方法:

type Column<T> = { [K in keyof T]-?: {
field: K;
columnFormatter?: (props: { value: T[K]; data: T; node: any }) => void;
} }[keyof T]

这种类型的一般形式,{[K in keyof T]-?: F<K>}[keyof T],被称为分发对象类型,正如在microsoft/TypeScript#47109中创造的那样;我们正在keyof T中的键上创建一个映射类型,然后立即用keyof T索引到它,以便为keyof T中的每个键K获得F<K>的联合。

特别是在这里,我们正在计算{ field: K; columnFormatter?: (props: { value: T[K]; data: T; node: any }) => void; }其中K是键的类型,T[K]是对应于该键的属性值的类型。

您可以验证Column<IPurchase>的评估结果是否完全符合所需类型。

操场链接到代码

相关内容

  • 没有找到相关文章

最新更新