在TypeScript中,我声明了一个这样的接口:
export default interface MyDTO {
readonly num: string;
readonly entitle: string;
readonly trb: string;
readonly ucr: string;
readonly dcr: string;
readonly udm?: string;
readonly ddm?: string;
}
使用函数,我想访问一个属性的值,其名称包含在变量中。
private doSomething(dto: MyDTO, property: string): any {
let label: any;
if (['dcr', 'ddm'].includes(property)) {
label = doSomethingElse(dto[property]);
} else {
label = dto[property];
}
return label;
}
不幸的是,TypeScript给了我以下错误消息:
元素隐式具有"any"类型,因为类型的表达式 "字符串"不能用于索引类型"MyDTO"。 无索引签名 在类型上找到类型为"字符串"的参数 'MyDTO'.ts(7053(
请问有人有想法吗?
谢谢
这是因为MyDTO
显式命名了属性,但你使用的是泛型字符串作为索引,所以 TypeScript 说它不能保证传递到doSomething
函数中的任何字符串实际上都与接口上的属性名称匹配。
TypeScript 2.1 中引入的一个很好的解决方法是keyof
.这允许您显式键入某些内容作为某个类/接口的键。
这将 A. 摆脱您看到的 TS 错误,B. 还检查以确保您的函数的任何调用方实际上都传递了有效的密钥。
export default interface MyDTO {
readonly num: string;
readonly entitle: string;
readonly trb: string;
readonly ucr: string;
readonly dcr: string;
readonly udm?: string;
readonly ddm?: string;
}
function doSomething(dto: MyDTO, property: keyof MyDTO): any {
let label: any;
if (['dcr', 'ddm'].includes(property)) {
label = doSomethingElse(dto[property]);
} else {
label = dto[property];
}
return label;
}
doSomething(obj, "foo") // is a TS error
doSomething(obj, "num") // is valid
@mhodges,根据您的建议,这是我修改后的函数,它似乎运行良好。 但是在以下情况下,我必须添加"as string",否则会出现以下错误:
类型 'string | keyof V '不能用于索引类型' V'.ts (2536(
public getDefaultComparator(property: keyof V | string, v1: V, v2: V): number {
let compareReturn = 0;
if (v1.hasOwnProperty(property)) {
const compareValue1 = v1[property as string];
const compareValue2 = v2[property as string];
if (compareValue1 > compareValue2) {
compareReturn = 1;
} else if (compareValue1 < compareValue2) {
compareReturn = -1;
}
}
return compareReturn;
}
在tsconfig.json文件中。设置"严格":真 -->假。
这对我有用。