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

问题描述 投票:0回答:4

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

`-- [email protected]

验证安装:

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'.
typescript
4个回答
246
投票

如果您使用的是 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


19
投票

我怀疑这与 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 规范的问题,或者也许他们只是还没有抽出时间来修复这个问题。


3
投票

请注意,Typescript 5.0 已弃用以下写入选项,并在 Typescript 5.5 中删除:

https://devblogs.microsoft.com/typescript/announcing-typescript-5-0-beta/#deprecations-and-default-changes

不要使用这个“解决方案”...

您可以使用编译器选项来防止此错误,而不会失去整个严格的空检查

"suppressImplicitAnyIndexErrors": true

https://www.typescriptlang.org/tsconfig#suppressImplicitAnyIndexErrors


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

这就是我必须做的才能让编译器满意

© www.soinside.com 2019 - 2024. All rights reserved.