我收到的数据需要映射到我为对象分配键时为响应声明的接口,该接口显示错误TS7017: Element implicitly has an 'any' type because type 'Idetails' has no index signature.
,有什么解决的办法吗?
main.ts
public Responsehandler(@Body() data: any): any {
const response: Idetails = {} as Idetails;
if (data.details === undefined || data.details === null) {
return data;
}
if (data.details) {
response.details.lineOfBusiness = "PBM";
Object.keys(data.details).forEach((key) => {
response.details[key] = data.details[key]
});
}
return response;
}
interface.ts
export interface Idetails {
primary:balanceDetails;
secondary: balanceDetails;
}
export interface balanceDetails {
beginningBalance: string;
endingBalance: string;
}
答案 0 :(得分:1)
我猜想您正在遇到Object.keys(obj)
返回string[]
而不是(keyof typeof obj)[]
之类的问题。这是一个common issue和reported一个lot。 Object.keys()
必须返回string[]
的原因是因为TypeScript中的类型是 open ,也就是说,对象必须至少具有 描述的属性匹配的类型。因此,唯一的类型安全返回值是string[]
。有关更多信息,请参见this comment。
这意味着假设data.details
的类型为Idetails
(我看不到您的代码... data
的类型仅为any
;您应该进一步说明),您所知道的就是它至少具有{em> primary
和secondary
属性,但可能还有更多。例如,data.details
可能是
const details = {
primary: { beginningBalance: "$0", endingBalance: "$200" },
secondary: { beginningBalance: "25¢", endingBalance: "10¢" },
tertiary: { beginningBalance: "₿100,000", endingBalance: "₿0.001" }
}
因此key
并不是response.details
的有效索引,因为key
可能是"teritary"
。
最简单的处理方法是assert Object.keys(data.details)
仅返回您知道的密钥。当然,有可能在运行时会有额外的键,并且代码会将这些额外的属性仅复制到response.details
...这可能是无害的,因为它不会阻止response.details
成为有效的Idetails
。这是您的操作方法:
(Object.keys(data.details) as (keyof Idetails)[]).forEach((key) => {
response.details[key] = data.details[key]; // okay
});
请注意,我们正在使用as
关键字来断言Object.keys(data.details)
返回了(keyof Idetails)[]
。现在,将key
推断为"primary" | "secondary"
,并且编译器对分配感到满意。
在要防止复制额外属性的情况下,还有其他方法可以解决此问题,例如,手动指定要复制的键的数组而无需完全检查data.details
:
// helper function to narrow array to string literals
const stringLiterals = <T extends string[]>(...args: T) => args;
// stringLiterals("primary", "secondary") is inferred as type ["primary", "secondary"]
stringLiterals("primary", "secondary").forEach((key) => {
response.details[key] = data.details[key]; // okay
});
现在这是完全类型安全的,不需要任何类型声明,但是可能比它值得的麻烦更多。
希望有所帮助;祝你好运!