元素隐式具有'any'类型,因为类型 'string' 的表达式不能用于索引 Angular 中的类型



在尝试为reduce方法内的数据设置类型时,我在angular应用程序中遇到了typescript错误。

error TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'ICar'. 
No index signature with a parameter of type 'string' was found on type 'ICar'.

后端侧向我发送以下对象数组,我将其传递给getCarProperty函数:

[
{
created: null
id: "124545484822"
details: {
name: "Ford focus"
number: "128888"
}
status: "working"
usedFrom: null
usedUntil: null
},
{
created: null
id: "99525484827"
details: {
name: "Honda Accord"
number: "598402"
}
status: "working"
usedFrom: null
usedUntil: null
}
]

以下是功能的样子:

getCarProperty = (obj: ICar, path: string): any => {
if (path.indexOf('.') > -1) {
return path.split('.').reduce((o: ICar, p: string) => {
return o && o[p]; <----- HERE IS THE ISSUE
}, obj);
}
return Array.from(path).reduce((o: ICar, p: string) => {
return o && o[p]; <------ Here is the issue
}, obj);
};

details.name属性通过path参数时,我可以得到name属性的值(例如"Ford focus"one_answers"Honda Accord"(。

以下是用于此数据的接口:

export interface IDetail {
name: string;
number: string;
}
export interface IContract {
created: string;
id: string;
detail: IDetail;
status: string;
usedFrom: string;
usedUntil: string;
}

我尝试应用不同的解决方案,如[propName askeyofICar]或设置泛型类型,但都没有成功。那么,这里出了什么问题?

感谢您的帮助。

问题是reduce回调期望一个符合ICar接口的对象,这仅在reduce回叫的第一次迭代中为真,在reduce回调的下一次迭代中,您将不再接收到ICar类型的对象(仅IDetailsstring(,因此约束失败。基本上,每个迭代的返回都返回一个不同的类型,这就是为什么你不能在那里使用特定的类型,但在某些情况下你可以使用类型的并集。

要解决您的问题,只需将ICar类型替换为any,如下所示。我认为这没有任何问题,因为您仍在检查getCarProperty函数参数。

getCarProperty = (obj: ICar, path: string): any => {
if (path.indexOf('.') > -1) {
return path.split('.').reduce((o: any, p: string) => {
return o && o[p];
}, obj);
}
return Array.of(path).reduce((o: any, p: string) => {
return o && o[p];
}, obj);
};

如果你真的想保留类型,并且不想使用any,你可以尝试下面的函数,但我看不出有多大优势,因为你已经在键入函数参数了。

function getCarProperty(obj: ICar, path: string): any {
type CarOrDetailType = ICar | IDetail; // <-- All the possibilities for the reduce `previousValue` callback parameter. If the ICar interface changes, you might need to adjust this.
type CarOrDetailKey = keyof CarOrDetailType;
if (path.indexOf('.') > -1) {
const typedPath = path.split('.') as Array<CarOrDetailKey>;
return typedPath.reduce((o: CarOrDetailType, p: CarOrDetailKey): any => {
return o && o[p];
}, obj);
}
const typedPath = Array.of(path) as Array<CarOrDetailKey>;
return typedPath.reduce((o: CarOrDetailType, p: CarOrDetailKey) => {
return o && o[p];
}, obj);
}

我在你的代码中发现了另外两个问题,但可能是你复制错误,它们是:

  • 您的模拟数据在每个属性后都没有comas,因此它没有有效的语法
  • 您在字符串上使用了Array.from(path),但可能想要Array.of(path)

最新更新