typescript 打字稿:类型中缺少索引签名
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/37006008/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Typescript: Index signature is missing in type
提问by Manu
I want MyInterface.dic
to be like a dictionary name: value
, I define it as follows:
我想像MyInterface.dic
一本字典name: value
,我定义如下:
interface MyInterface {
dic: { [name: string]: number }
}
Now I create a function which waits for my type:
现在我创建一个等待我的类型的函数:
function foo(a: MyInterface) {
...
}
And the input:
和输入:
let o = {
dic: {
'a': 3,
'b': 5
}
}
I'm expecting foo(o)
to be correct, but the compiler is falling:
我希望foo(o)
是正确的,但编译器正在下降:
foo(o) // Typescript error: Index signature is missing in type { 'a': number, 'b': number }
I know there is a possible casting: let o: MyInterface = { ... }
which do the trick but the question is, whytypescript is not recognizing my type?
我知道有一个可能的转换:let o: MyInterface = { ... }
哪个可以解决问题,但问题是,为什么打字稿不能识别我的类型?
Extra: works fine if o
is declared inline:
额外:如果o
声明为内联,则工作正常:
foo({
dic: {
'a': 3,
'b': 5
}
})
回答by Tim Perry
The problem is that when the type is inferred, then the type of o
is:
问题是,当推断出类型时,则类型o
为:
{ dic: { a: number, b: number } }
That's not the same as { dic: { [name: string]: number } }
. Critically, with the top signature you're not allowed to do something like o.dic['x'] = 1
. With the 2nd signature you are.
这与{ dic: { [name: string]: number } }
. 至关重要的是,使用顶级签名,您不能执行类似o.dic['x'] = 1
. 有了第二个签名,你就是。
They are equivalent types at runtime (indeed, they're the exact same value), but a big part of TypeScript's safety comes from the fact that these aren't the same, and that it'll only let you treat an object as a dictionary if it knows it's explicitly intended as one. This is what stops you accidentally reading and writing totally non-existent properties on objects.
它们在运行时是等价的类型(实际上,它们是完全相同的值),但是 TypeScript 的安全性很大一部分来自于它们不相同的事实,并且它只会让您将对象视为字典,如果它知道它明确地打算作为一个。这就是阻止您意外读取和写入对象上完全不存在的属性的原因。
The solution is to ensure TypeScript knows that it's intended as a dictionary. That means:
解决方案是确保 TypeScript 知道它是作为字典使用的。这意味着:
Explicitly providing a type somewhere that tells it it's a dictionary:
let o: MyInterface
Asserting it to be a dictionary inline:
let o = { dic: <{ [name: string]: number }> { 'a': 1, 'b': 2 } }
Ensuring it's the initial type that TypeScript infers for you:
foo({ dic: { 'a': 1, 'b': 2 } })
在某处显式提供一个类型,告诉它是一个字典:
let o: MyInterface
断言它是一个内联字典:
let o = { dic: <{ [name: string]: number }> { 'a': 1, 'b': 2 } }
确保它是 TypeScript 为您推断的初始类型:
foo({ dic: { 'a': 1, 'b': 2 } })
If there's a case where TypeScript thinks it's a normal object with just two properties, and then you try to use it later as a dictionary, it'll be unhappy.
如果有一种情况,TypeScript 认为它是一个只有两个属性的普通对象,然后你稍后尝试将它用作字典,它会不高兴。