使用字符串类型参数访问枚举时出现 TypeScript TS7015 错误
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/36316326/
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 TS7015 error when accessing an enum using a string type parameter
提问by Neoheurist
I am new to TypeScript and I don't understand the what I need to do to fix the line that generates the TS7015 error (referencing an enum member using a string variable) because the line immediately following that does not error (referencing an enum member using a string literal):
我是 TypeScript 的新手,我不明白我需要做什么来修复产生 TS7015 错误的行(使用字符串变量引用枚举成员),因为紧随其后的行不会出错(引用枚举成员)使用字符串文字):
enum State {
Happy = 0,
Sad = 1,
Drunk = 2
}
function Emote(enumKey:string) {
console.log(State[enumKey]); // error TS7015: Element implicitly has an 'any' type because index expression is not of type 'number'.
console.log(State["Happy"]); // no error
}
"noImplicitAny": true
is set in the project's tsconfig.json
the error is detected
"noImplicitAny": true
在项目的设置中tsconfig.json
检测到错误
"noImplictAny": false
is set in the project's tsconfig.json
no error is detected
"noImplictAny": false
设置在项目的tsconfig.json
未检测到错误
I'm compiling with "ntypescript": "^1.201603060104.1"
我正在编译 "ntypescript": "^1.201603060104.1"
I'm now compiling with "tsc": "1.8.10"
我现在正在编译 "tsc": "1.8.10"
C:>npm install -g typescript
`-- [email protected]
Verifying installation:
验证安装:
C:\>tsc --version
Version 1.8.10
Here's my tsconfig.json
file:
这是我的tsconfig.json
文件:
{
"compileOnSave": true,
"compilerOptions": {
"target": "ES5",
"module": "System",
"moduleResolution": "node",
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"removeComments": true,
"noImplicitAny": true,
"sourceMap": true,
"mapRoot": "map/",
"diagnostics": true
},
"exclude": [
"node_modules",
"typings"
]
}
Here's the compiler output:
这是编译器的输出:
C:\>tsc
test.ts(8,17): error TS7015: Element implicitly has an 'any' type because index expression is not of type 'number'.
回答by Steven Barnett
If you're using TypeScript 2.1+, you can change enumKey
's type to keyof typeof State
, like this:
如果您使用的是 TypeScript 2.1+,则可以将enumKey
的类型更改为keyof typeof State
,如下所示:
function Emote(enumKey: keyof typeof State) {...}
or, if the function's input is required to be a string
, this:
或者,如果函数的输入需要是 a string
,则:
var state : State = State[enumKey as keyof typeof State];
Explanation:
解释:
The error is generated because TypeScript, being an arbitrary string, doesn't know whether enumKey
is the name of a member of State
. TypeScript 2.1+ introduced the keyof
operator which returns a union of the known, public property names of a type. Using keyof
allows us to assert that the property is indeed in the target object.
是因为打字稿产生的错误,作为一个任意字符串,不知道是否enumKey
是其成员的名字State
。TypeScript 2.1+ 引入了keyof
返回类型的已知公共属性名称的联合的运算符。Usingkeyof
允许我们断言该属性确实在目标对象中。
However, when you create an enum, TypeScript actually produces both a type(which is always a subtype of number
) and a value(the enum object that you can reference in expressions). When you write keyof State
, you're actually going to get a union of the literal property names of number
. To instead get the property names of the enum object, you can use keyof typeof State
.
但是,当您创建枚举时,TypeScript 实际上会同时生成类型(始终是 的子类型number
)和值(您可以在表达式中引用的枚举对象)。当您编写 时keyof State
,您实际上将获得 的文字属性名称的并集number
。要获取枚举对象的属性名称,您可以使用keyof typeof State
.
Sources:
资料来源:
https://github.com/Microsoft/TypeScript/issues/13775#issuecomment-276381229https://www.typescriptlang.org/docs/handbook/advanced-types.html#index-types
https://github.com/Microsoft/TypeScript/issues/13775#issuecomment-276381229 https://www.typescriptlang.org/docs/handbook/advanced-types.html#index-types
回答by Ken Smith
I suspect it has to do with TS 1.8.x's new support for string literals in these situations. TS happens to know that "Happy" is a valid string index, but it doesn't know whether enumKey
will be or not. You can fix it by casting it to an <any>
, like so:
我怀疑这与 TS 1.8.x 在这些情况下对字符串文字的新支持有关。TS 碰巧知道“Happy”是一个有效的字符串索引,但它不知道是否enumKey
会是。您可以通过将其强制转换为 来修复它<any>
,如下所示:
function Emote(enumKey:string) {
console.log(State[enumKey]); // error TS7015: Element implicitly has an 'any' type because index expression is not of type 'number'.
console.log(State["Melancholy"]); // error TS7015: Element implicitly has an 'any' type because index expression is not of type 'number'.
console.log(State["Happy"]); // no error
console.log(State[<any>enumKey]); // no error
console.log(State[<any>"Melancholy"]); // no error
}
(BTW, I think this is new: I couldn't reproduce this error with 1.8.9, but as soon as I upgraded to 1.8.10, I could.)
(顺便说一句,我认为这是新的:我无法在 1.8.9 中重现此错误,但是一旦我升级到 1.8.10,我就可以。)
Also interestingly, I would have expected this to work without the error, but it doesn't:
同样有趣的是,我原以为这不会出错,但它不会:
function TypedEmote(enumKey:'Happy'|'Sad'|'Drunk'){
console.log(State[enumKey]);
}
Must be something about the TS spec I don't understand, or perhaps they just haven't gotten around to fixing that bit yet.
一定是我不明白的 TS 规范,或者他们只是还没有开始修复那一点。
回答by HolgerJeromin
You can prevent this error with the compiler option without loosing the whole strict null checks
您可以使用编译器选项防止此错误,而不会丢失整个严格的空检查
"suppressImplicitAnyIndexErrors": true
回答by Sharpiro
var stateName = "Happy"
var state = <State>parseInt(State[<any>stateName]);
This is what I had to do to make the compiler happy
这是我必须做的才能让编译器满意