我希望 MyInterface.dic
像字典一样 name: value
,我将其定义如下:
interface MyInterface {
dic: { [name: string]: number }
}
现在我创建一个等待我的类型的函数:
function foo(a: MyInterface) {
...
}
和输入:
let o = {
dic: {
'a': 3,
'b': 5
}
}
我期待 foo(o)
是正确的,但编译器正在下降:
foo(o) // TypeScript error: Index signature is missing in type { 'a': number, 'b': number }
我知道有一个可能的转换: let o: MyInterface = { ... }
这可以解决问题,但 为什么 TypeScript 无法识别我的类型?
额外:如果 o
被声明为内联,则工作正常:
foo({
dic: {
'a': 3,
'b': 5
}
})
原文由 Manu Artero 发布,翻译遵循 CC BY-SA 4.0 许可协议
问题是当推断类型时,那么
o
的类型是:这与
{ dic: { [name: string]: number } }
。至关重要的是,使用顶部签名您不能执行类似o.dic['x'] = 1
的操作。有了第二个签名,你就是。它们在运行时是等价的类型(实际上,它们的值完全相同),但是 TypeScript 的安全性很大一部分来自于它们不一样的事实,它只会让你将对象视为字典,如果它知道它明确地打算作为一个。这就是阻止您意外读取和写入对象上完全不存在的属性的原因。
解决方案是确保 TypeScript 知道它是用作字典的。这意味着:
let o: MyInterface
let o = { dic: <{ [name: string]: number }> { 'a': 1, 'b': 2 } }
foo({ dic: { 'a': 1, 'b': 2 } })
如果有一种情况,TypeScript 认为它是一个只有两个属性的普通对象,然后你稍后尝试将它用作字典,它会不高兴。