我有一个接口:
interface MyInterface {
field_1 : string
field_2 : string
// ... other fields with a certain number
}
我有一个getter函数,它接收MyInterface的一个实例,并且应该动态地检索这个对象的属性值
const myFactory = (myInstance:MyInterface):string => {
// Here some logic to retrieve a specific number
// for convenience lets say that the output of this logic is 1
let output = 1
return myInstance[`field_${output}`] // <=== This does not work since it calls a property of the interface dynmically
}
如何动态调用接口的属性?
我看到keyof
操作员:但我不知道如何在这里使用
选项1:
type myKey = `field_${'1' | '2' | '3'}`
const output = '3'
const fieldKey: myKey = `field_${output}`
选项2:
const fieldKey = `field_${output}` as keyof MyInterface
return myInstance[fieldKey]
as
关键字只能欺骗TypeScript让您做您认为正在做的事情。
对于TypeScript 3,这可能是唯一的方法。
如果您使用的是TypeScript 4+,则可以使用Template Literal Type:对生成的fieldKey
进行一些验证
type MyField = `field_${number}`;
type MyType = Record<MyField, string>;
const myFactory = (instance: MyType): string => {
let n = 12;
const fieldName: keyof MyType = `field_${n}`;
return instance[fieldName];
}
在这个代码段中,如果给n
(如"x"
(一个非数字值,那么它将屈服于被拒绝的"field_x"
(即在编译时被TypeScript检测为不正确(。
和你写的一样:
const fieldName: keyof MyType = `wrong_${n}`;
因为CCD_ 7在CCD_。
如果您需要构建一个更大的MyType
,其中包含与field_N
形状不同的其他字段,则可以声明:
type LargerType = MyType & {
anotherField: string;
};
最后,如果你需要限制数字,你可以声明:
type MyField = `field_${1 | 2 | 3 | 4}`;
在这种情况下,具有n = 12
的代码片段会产生错误,因为12
已被禁止。如果n
值是动态获得的,而不是像这里那样推断的,则需要将声明为:
let n: 1|2|3|4;
(或者更有可能的是,您会为接受的号码声明type
,因为现在您在多个地方使用它们。(