TypeScript:强制一致的对象键作为类型参数
我有一个TypeScript:强制一致的对象键作为类型参数,typescript,Typescript,我有一个列界面,可以根据键渲染行中的值: interface Column<Row, Field extends keyof Row> { key: Field; render: (value: Row[Field]) => React.ReactNode; } 由于字段被实例化为用户的键,而不是特定的键。啊,我喜欢这种类型的问题。您遇到的一个问题是TypeScript不允许您省略类型参数和。您可以说类似于列,其中行类型参数是从您传递给它的对象文本推断出来的。
列
界面,可以根据键渲染行中的值:
interface Column<Row, Field extends keyof Row> {
key: Field;
render: (value: Row[Field]) => React.ReactNode;
}
由于
字段
被实例化为用户的键
,而不是特定的键。啊,我喜欢这种类型的问题。您遇到的一个问题是TypeScript不允许您省略类型参数和。您可以说类似于列
,其中行
类型参数是从您传递给它的对象文本推断出来的。我们不能直接这么做。。。但我们可以间接获得这种效果:
function columnsFor<Row>() {
function of<Field extends keyof Row>(column: Column<Row, Field>): Column<Row, Field> {
return column;
}
return of;
}
userColumn
函数将只接受某个Column
类型的参数,并从该参数推断字段
。现在,您可以继续制作该阵列:
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
];
const列=[
用户列({
密钥:“id”,
渲染(id:编号){
返回id;
}
}),//确定,推断为列
用户列({
键:“名称”,
渲染(名称:字符串){
返回名称;
}
}),//确定,推断为列
用户列({
密钥:“id”,
渲染(id:字符串){
返回id;
}
})//错误如预期
];
希望这对你有用。祝你好运 联合类型如何:id:number | string;看一看:我不确定这有什么帮助:我希望TypeScript只允许
id:number
作为参数。哦,好的。不过我不明白你的问题。谢谢,我怀疑这样的事情可能会发生,但我不确定TypeScript中的惯用方法是什么。我希望有一种方法可以保证使用类型系统的正确使用,因为仍然有可能产生不正确的代码。如果TypeScript具有不透明类型,则可以通过使列
不透明来使用此方法,这样所有列都必须使用columnFor
创建。您可以使Column
成为一个具有私有构造函数的类,并为其提供一个静态方法,以仅生成所需的列
对象。上面的代码并不完全是错误的;你告诉TypeScript你想要一个列
数组,这不是你真正的意思。谢谢,我来看看私有构造函数。至于原始代码是否正确:我认为该列不是列的有效实例
function columnsFor<Row>() {
function of<Field extends keyof Row>(column: Column<Row, Field>): Column<Row, Field> {
return column;
}
return of;
}
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
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
];