我是 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
设置在项目的tsconfig.json
中检测到错误
"noImplictAny": false
设置在项目的 tsconfig.json
中未检测到错误
我正在使用
"ntypescript": "^1.201603060104.1"
进行编译
我现在正在使用 "tsc": "1.8.10"
进行编译
C:>npm install -g typescript
`-- typescript@1.8.10
验证安装:
C:\>tsc --version
Version 1.8.10
这是我的 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"
]
}
这是编译器输出:
C:\>tsc
test.ts(8,17): error TS7015: Element implicitly has an 'any' type because index expression is not of type 'number'.
noImplicitAny
设置为 false
会使错误消失...
ntypescript
看起来它主要面向希望直接使用 TypeScript 编译器 API 的人。我想你想要 typescript
...
如果您使用的是 TypeScript 2.1+,您可以将 enumKey
的类型更改为 keyof typeof State
,如下所示:
function Emote(enumKey: keyof typeof State) {...}
或者,如果函数的输入需要是 string
,则:
var state : State = State[enumKey as keyof typeof State];
解释:
因为 enumKey
是任意的 string
,TypeScript 不知道 enumKey
是否是 State
的成员的名称,因此会产生错误。 TypeScript 2.1 引入了 keyof
运算符,它返回一个类型的已知公共属性名称的联合。使用 keyof
允许我们断言该属性确实在目标对象中。
但是,当您创建枚举时,TypeScript 实际上会同时生成 type(通常是 number
的子类型)和 value(您可以引用的枚举对象在表达式中)。当您编写 keyof State
时,您实际上将获得 number
的文字属性名称的并集。要获取枚举对象的属性名称,您可以使用 keyof typeof State
。
资料来源:
https://github.com/Microsoft/TypeScript/issues/13775#issuecomment-276381229 https://www.typescriptlang.org/docs/handbook/enums.html#enums-at-compile-time
我怀疑这与 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
}
(顺便说一句,我认为这是新的:我无法用 1.8.9 重现此错误,但一旦我升级到 1.8.10,我就可以了。)
同样有趣的是,我本来希望这可以在没有错误的情况下工作,但事实并非如此:
function TypedEmote(enumKey:'Happy'|'Sad'|'Drunk'){
console.log(State[enumKey]);
}
一定是关于我不理解的 TS 规范的一些东西,或者他们可能还没有解决这个问题。
TypedEmote()
方法中尝试用 'Happy'|'Sad'|'Drunk'
类型做的事情。就像我说的,是的,我认为它应该有效,但似乎没有。很想知道你是否能找到一种方法来做到这一点。
state: State = State[<any>"Happy"]
也不起作用 - “类型 'string' 不可分配给类型 'State'”
any
类型,就像我在这里所做的那样 if(<any>this.gravity === GravityType[<any>dir])
或者,看看 Sharpiro's answer,它有点更优雅。
您可以使用编译器选项来防止此错误,而不会丢失整个严格的空检查
"suppressImplicitAnyIndexErrors": true
https://www.typescriptlang.org/tsconfig#suppressImplicitAnyIndexErrors
var stateName = "Happy"
var state = <State>parseInt(State[<any>stateName]);
这就是我必须做的让编译器满意
public rateType: keyof typeof RegularTypeEnum | BlockedTypeEnum;
,任何人都可以理解该属性的可能值。谢谢。State[enumKey as keyof typeof State]