interface Model {
[key: string]: string | number | boolean | Model | Model[];
}
interface ApiResponse {
[key: string]: Model[];
}
async function main(): Promise<void> {
const r = await api('foos_and_bars');
console.log(r.bars[0].baz.name); // Problem
console.log(r.foos[0].fuzzies[1].name); // Implicit any
}
main();
async function api(endpoint: string): Promise<ApiResponse> {
// Faked response:
return {
foos: [ { name: 'Foo 1', fuzzies: [{ name: 'Fuzzy 1' }, { name: 'Fuzzy 2'}] } ],
bars: [ { name: 'Bar 1', baz: { name: 'Baz 1' } } ]
}
}
在上面的TypeScript代码中,我打算使用Model
接口,我打算像这样运行:
但是如果我使用这个接口并尝试读取它上面的一些属性,我会得到编译器错误,我不会期望。
对于第一个控制台日志,我得到:
Property 'name' does not exist on type 'string | number | boolean | Model | Model[]'.
Property 'name' does not exist on type 'string'.
对于第二个控制台日志(启用了noImplicitAny
标志):
Element implicitly has an 'any' type because type 'string | number | boolean | Model | Model[]' has no index signature.
我的界面在这里做错了什么?
答案 0 :(得分:3)
编译器是正确的。
第一条错误消息:
console.log(r.bars[0].baz.name);
表示:
财产&#39;名称&#39;类型&#39;字符串|中不存在号码|布尔值|型号|模型[]&#39 ;.
上不存在
财产名称&#39;类型&#39;字符串&#39;。
情况确实如此。编译器不知道r.bars[0].baz
属于Model
类型,它知道可以属于该类型,但它也可以是string
}(或number
等)
联盟类型仅具有所有包含类型共享的属性
您可以通知编译器您知道类型是什么:
console.log((r.bars[0].baz as Model).name);
相同的错误几乎相同,r.foos[0].fuzzies
的类型未知,它可能是联合中的一种类型,因此您需要以相同的方式让编译器知道:
console.log((r.foos[0].fuzzies as Model[])[1].name);