打字稿:执行一致的对象键类型参数
我有一个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
,而不是一个特定的键。
啊,我喜欢这种类型的问题。你遇到的一个问题是,TypeScript不会让你遗漏类型参数和infer their types。你想说一些类似于Column<User>
的地方,其中类型参数是从你传递给它的对象字面量推断出来的。好了,我们不能这样做直接......但我们可以间接得到这样的效果:
function columnsFor<Row>() {
function of<Field extends keyof Row>(column: Column<Row, Field>): Column<Row, Field> {
return column;
}
return of;
}
功能columnsFor
是不大不小的curried功能;您可以明确设置类型参数,并且它返回另一个函数,该函数接受Column<Row,Field>
对象任意有效类型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
。现在,您可以继续制作该阵列:
const columns = [
userColumn({
key: "id",
render(id: number) {
return id;
}
}), // ok, inferred as Column<User,"id">
userColumn({
key: "name",
render(name: string) {
return name;
}
}), // ok, inferred as Column<User,"name">
userColumn({
key: "id",
render(id: string) {
return id;
}
}) // error as expected
];
希望对您有用。祝你好运!
谢谢,我怀疑这样做可能是可能的,但我不确定TypeScript中的惯用方法是什么。我希望有一种方法可以保证使用类型系统的正确使用,因为它仍然有可能产生不正确的代码。如果TypeScript通过使'Column'不透明来实现不透明类型,那么所有列都必须使用'columnFor'来创建。 –
你可以使用一个私有构造函数使'Column'成为一个类,并给它一个静态方法来产生所需的'Column'对象。上面的代码并不完全错误;你告诉TypeScript你需要一个'Column
谢谢,我会看看私人构造函数。至于原始代码没有错误:我认为这个列不是'Column
工会类型如何: id:number |串; 看看: https://stackoverflow.com/questions/38628115/what-does-the-pipe-mean-in-typescript – proti
我不知道这有什么帮助:我希望TypeScript只允许'ID:数字“作为参数。 –
哦,好的。虽然不理解你的问题。 – proti