我有一个Column
接口,可以根据键从行中呈现值:
interface Column<Row, Field extends keyof Row> {
key: Field;
render: (value: Row[Field]) => React.ReactNode;
}
如果我明确设置每列的类型,那么我会得到所需的行为。例如,以下内容无效:
interface User {
id: number;
name: string;
}
const column: Column<User, "id"> = {
key: "id",
render(id: string) {
return id;
}
};
因为id
属性是字符串,而不是数字。有没有办法获得此行为,而无需单独指定每列的类型?例如,以下类型检查:
const columns: Array<Column<User, keyof User>> = [
{
key: "id",
render(id: string) {
return id;
}
}
];
因为Field
被实例化为keyof User
,而不是特定的密钥。
答案 0 :(得分:1)
Column<User>
之类的内容,其中Row
类型参数是从传递给它的对象文字中推断出来的。好吧,我们不能直接这样做......但我们可以间接地得到这个效果:
function columnsFor<Row>() {
function of<Field extends keyof Row>(column: Column<Row, Field>): Column<Row, Field> {
return column;
}
return of;
}
函数columnsFor
是一种curried函数;您可以显式设置Row
类型参数,并返回另一个函数,该函数接受{em>任何有效类型Column<Row,Field>
的{{1}}对象。以下是您使用它的方式:
Field
const userColumn = columnsFor<User>();
const goodColumn = userColumn({
key: "id",
render(id: number) {
return id;
}
}); // ok, inferred as Column<User, "id">
const badColumn = userColumn({
key: "id",
render(id: string) {
return id;
}
}); // error as expected
函数只接受某种userColumn
类型的参数,并从该参数中推断出Column<User, Field>
。现在你可以继续制作那个阵列了:
Field
希望这对你有用。祝你好运!