使用字符串类型参数访问枚举时出现 TypeScript TS7015 错误
Posted
技术标签:
【中文标题】使用字符串类型参数访问枚举时出现 TypeScript TS7015 错误【英文标题】:TypeScript TS7015 error when accessing an enum using a string type parameter 【发布时间】:2016-07-18 21:34:30 【问题描述】:我是 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
中检测到错误
在项目的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'.
【问题讨论】:
您在寻找什么样的答案?您已经注意到将noImplicitAny
设置为false
会使错误消失...
我不想关闭 noImplicitAny 检查,而是想修复代码以使其通过 noImplicitAny 检查。但更重要的是,我不明白为什么第一个引用错误,第二个引用通过(从类型上讲,两个枚举引用的类型是相同的......或者他们真的不是,我只是错过了一些东西(可能很明显) )
您使用的是什么版本的打字稿?我没有得到该代码的隐式任何类型错误。
"noImplicitAny": true,版本 1.8.2,没有错误,State[enumKey]
ntypescript
看起来主要是为那些想直接使用 TypeScript 编译器 API 的人准备的。我想你想要typescript
...
【参考方案1】:
我怀疑这与 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 规范的某些内容,或者他们可能还没有解决这个问题。
【讨论】:
有趣的是,“Melancholy”也出现了错误——让我怀疑编译器推断出有一个(未命名的)派生类型的字符串,并且仅限于“Happy”、“Sad”和“醉” --- 也许我可以明确定义这样的类型并使用它...... @Neoheurist - 这或多或少是我在上面的TypedEmote()
方法中尝试使用 'Happy'|'Sad'|'Drunk'
类型所做的。就像我说的,是的,我认为它应该有效,但似乎没有。很想知道你是否能找到办法。
state: State = State[<any>"Happy"]
也不起作用 - “类型 'string' 不可分配给类型 'State'”
@AlexOkrushko 不幸的是,在这种情况下,它似乎需要两边都有一个any
类型,就像我在这里所做的if(<any>this.gravity === GravityType[<any>dir])
或者,看看Sharpiro's answer,它是一个bit 更优雅。【参考方案2】:
var stateName = "Happy"
var state = <State>parseInt(State[<any>stateName]);
为了让编译器满意,我必须这样做
【讨论】:
它有效,但它很丑......史蒂文的解决方案要好得多。 (但请注意,它只是 TS 2.1+,所以 YMMV)【参考方案3】:您可以使用编译器选项来防止此错误,而不会丢失整个严格的空检查
"suppressImplicitAnyIndexErrors": true
https://www.typescriptlang.org/tsconfig#suppressImplicitAnyIndexErrors
【讨论】:
【参考方案4】:如果您使用的是 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 好处的其他解决方案。使用这个public rateType: keyof typeof RegularTypeEnum | BlockedTypeEnum;
,任何人都可以理解该属性的可能值。谢谢。
你的回答太好了,应该在官方文档里。
我很欣赏这个答案,但令人恼火的是,类型安全总是想办法将非常简单明了的代码变成类型声明的混淆。
哇,这个答案对我有用,但看着这个让我头疼:State[enumKey as keyof typeof State]
以上是关于使用字符串类型参数访问枚举时出现 TypeScript TS7015 错误的主要内容,如果未能解决你的问题,请参考以下文章
将字符串的 2darray 作为参数传递时出现“错误:类型的数组值”
使用 JDBC 写入编写 AWS Glue DynamicFrame 时出现 PostreSQL 枚举问题
PLS-00306:调用 'GET_LINE' 时参数的数量或类型错误。在 PL/SQL 中的函数中传递字符串参数时出现此错误