使用字符串类型参数访问枚举时出现TypeScript TS7015错误

Neo*_*ist 35 typescript

我是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
}
Run Code Online (Sandbox Code Playgroud)

"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
Run Code Online (Sandbox Code Playgroud)

验证安装:

C:\>tsc --version

Version 1.8.10
Run Code Online (Sandbox Code Playgroud)

这是我的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"
  ]
}
Run Code Online (Sandbox Code Playgroud)

这是编译器输出:

C:\>tsc

test.ts(8,17): error TS7015: Element implicitly has an 'any' type because index expression is not of type 'number'.
Run Code Online (Sandbox Code Playgroud)

Ste*_*ett 88

如果您使用的是TypeScript 2.1+,则可以将enumKey类型更改为keyof typeof State,如下所示:

function Emote(enumKey: keyof typeof State) {...}
Run Code Online (Sandbox Code Playgroud)

或者,如果函数的输入必须是a string,则:

var state : State = State[enumKey as keyof typeof State];
Run Code Online (Sandbox Code Playgroud)

说明:

生成错误是因为TypeScript是一个任意字符串,不知道是否enumKey是其成员的名称State.TypeScript 2.1+引入了keyof运算符,该运算符返回类型的已知公共属性名称的并集.使用keyof允许我们断言该属性确实在目标对象中.

但是,当您创建枚举时,TypeScript实际上同时生成一个类型(始终是其子类型number)和一个(您可以在表达式中引用的枚举对象).当你写作时keyof State,你实际上将得到一个文字属性名称的联合number.要获取枚举对象的属性名称,您可以使用keyof typeof State.

资料来源:

https://github.com/Microsoft/TypeScript/issues/13775#issuecomment-276381229 https://www.typescriptlang.org/docs/handbook/advanced-types.html#index-types

  • 哇,这个答案对我有用,但是看到这个让我头疼:“State[enumKey as keyof typeof State]” (2认同)

Ken*_*ith 16

我怀疑它与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
}
Run Code Online (Sandbox Code Playgroud)

(顺便说一句,我认为这是新的:我无法用1.8.9重现这个错误,但是一旦我升级到1.8.10,我就可以.)

同样有趣的是,我希望这可以在没有错误的情况下工作,但它不会:

function TypedEmote(enumKey:'Happy'|'Sad'|'Drunk'){
    console.log(State[enumKey]);
}
Run Code Online (Sandbox Code Playgroud)

必须是我不明白的TS规范,或者他们可能还没有解决这个问题.