【发布时间】:2019-01-22 07:55:37
【问题描述】:
我有如下接口来定义表的一列:
export interface IColumnDefinition<TRow, TField extends keyof TRow> {
field: TField;
label?: string;
formatter?: (value: TRow[TField], row: TRow) => string;
}
现在我想要的是只提供行的类型 (TRow),并让 TypeScript 根据 field 属性中的值自动推断字段的类型 (TField)。
现在假设我的行有以下界面:
interface User {
name: string;
birthDate: number;
}
我尝试的是以下内容:
const birthDateColumnDefinition: IColumnDefinition<User> = {
field: 'birthDate',
formatter: value => new Date(value).toDateString(),
}
这给了我以下错误:
通用类型 'IColumnDefinition
' 需要 2 个类型参数。
我也尝试过使用函数来创建定义,希望可以从参数中推断出类型:
function createColumnDefinition<TField extends keyof TRow>(
field: TField,
columnDef: Partial<IColumnDefinition<TRow, TField>>): IColumnDefinition<TRow, TField>
{
return {
...columnDef,
field,
};
}
const birthDateColumnDefinition = createColumnDefinition<User>('birthDate', {
formatter: (value, row) => new Date(value).toDateString(),
});
这给了我一个类似的错误:
排除了 2 个类型参数,但得到了 1 个。
但是,如果我还将该行作为参数包含在内,并一起删除所有通用参数,它可以正常工作:
function createColumnDefinition<TRow, TField extends keyof TRow>(
row: TRow,
field: TField,
columnDef: Partial<IColumnDefinition<TRow, TField>>): IColumnDefinition<TRow, TField>
{
return {
...columnDef,
field,
};
}
const user: User = {
name: 'John Doe',
birthDate: 549064800000,
};
const birthDateColumnDefinition = createColumnDefinition(user, 'birthDate', {
formatter: (value, row) => new Date(value).toDateString(),
});
这确实有效,但这不是一个选项,因为我在定义列时实际上没有一行。
那么有什么方法可以使这项工作(最好是使用接口而不是函数)?
【问题讨论】:
-
你可以在这两个地方用
keyof TRow替换TField,然后你只需要提供TRow。但是,您将丢失row[field]的特定类型。 -
是的,但我想在列定义的其他属性中使用
TField。以formatter的第一个参数为例。
标签: typescript