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

mznpcxlj  于 2023-03-09  发布在  TypeScript
关注(0)|答案(4)|浏览(133)

我是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
}

在项目的tsconfig.json中设置"noImplicitAny": true,检测到错误
在项目的tsconfig.json中设置"noImplictAny": false,未检测到错误
我用"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'.
osh3o9ms

osh3o9ms1#

如果您使用的是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允许我们Assert该属性确实在目标对象中。
但是,在创建枚举时,TypeScript实际上同时生成 * type *(通常是number的子类型)和 * 值 *(可以在表达式中引用的枚举对象)。当你写keyof State时,你实际上会得到number的字面属性名的并集。要想得到枚举对象的属性名,您可以使用keyof typeof State
资料来源:
https://github.com/Microsoft/TypeScript/issues/13775#issuecomment-276381229https://www.typescriptlang.org/docs/handbook/enums.html#enums-at-compile-time

ulydmbyx

ulydmbyx2#

我怀疑这与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,我认为这是新的:我无法在1.8.9中重现此错误,但一旦我升级到1.8.10,我就可以重现此错误。)
同样有趣的是,我本以为它不会出错,但它没有:

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

一定是关于TS规范的一些东西我不明白,或者也许他们只是还没有得到周围修复位。

bejyjqdl

bejyjqdl3#

您可以使用compiler选项防止此错误,而不会丢失整个严格的空值检查

"suppressImplicitAnyIndexErrors": true

https://www.typescriptlang.org/tsconfig#suppressImplicitAnyIndexErrors
请注意,此选项在Typescript 5.0中不建议使用,在Typescript 5.5中已删除:https://devblogs.microsoft.com/typescript/announcing-typescript-5-0-beta/#deprecations-and-default-changes

ukxgm1gy

ukxgm1gy4#

var stateName = "Happy"
var state = <State>parseInt(State[<any>stateName]);

这就是我必须做的让编译器满意的事情

相关问题