运行时未定义的枚举类型
运行时未定义的枚举类型
我遇到了一个问题,就是TypeScript编译器可以成功编译我的代码,但是运行时却给出了未定义类型的错误。
在我的应用程序中,我创建了一个名为types.ts
的文件,其中包含了一些在其他多个ts文件之间共享的内容。它包含一个字符串枚举类型,如下所示:
enum MyEnum { One = "one"; Two = "two"; }
当我像这样定义它时,编译器允许我在其他ts文件中使用它,并且似乎很满意。然而,在运行时,我得到了一个错误提示:"MyEnum未定义"。
我知道两种解决方法:
- 在使用它的文件中定义枚举。但是我认为这对其他想使用它的文件并没有解决问题。
- 在types.ts文件中使用"export",并在使用它的地方显式地导入每个类型。
我对TypeScript还很陌生,我觉得我可能对一些基本的东西有误解。
首先,我不明白为什么TypeScript编译器会愉快地编译我的代码,而运行时却会出现错误。如果我使用了declare
关键字,告诉编译器某些东西应该在运行时可用,那我会理解,但在这种情况下,我不明白为什么它应该假设枚举来自types.ts文件以外的地方。
其次,我希望在我的应用程序的某个全局位置定义类型,并且在任何地方都可以使用它们,而无需每次都导入它们。我该如何实现?或者这可能被认为是不好的做法吗?
我正在使用TypeScript 2.6,我的配置如下:
{ "compilerOptions": { /* 基本选项 */ "target": "es6", "module": "commonjs", "lib": ["es6", "es7", "esnext"], "sourceMap": true /* 生成对应的'.map'文件 */, "outDir": "build" /* 重定向输出结构到目录 */, "removeComments": true /* 不将注释输出到输出文件 */, /* 严格类型检查选项 */ "strict": true /* 启用所有严格类型检查选项 */, /* 其他检查 */ "noUnusedLocals": true /* 报告未使用的局部变量错误 */, "noUnusedParameters": true /* 报告未使用的参数错误 */, "noImplicitReturns": true /* 当函数中的所有代码路径都没有返回值时报错 */, "noFallthroughCasesInSwitch": true /* 报告switch语句中的穿透错误 */, "plugins": [{ "name": "tslint-language-service" }], "skipLibCheck": true // 因为firebase-sdk现在有错误的类型文件(2018年11月) }, "include": ["src/**/*"], "exclude": ["build"] }
在上述问题中,问题出现的原因是当引入重新导出的枚举时出现了运行时错误。具体来说,问题出现在component.ts文件中的import语句中。在这个文件中,尝试使用import { Part } from '../entities'来引入枚举,但是这样会导致错误。然而,当使用import { Part } from '../entities/layout'来引入枚举时,问题得到解决。
解决这个问题的方法有两种。第一种方法是直接使用import { Part } from '../entities/layout'来引入枚举。这种方法已经在上述代码中得到了验证,可以正常工作。
另一种方法是停止使用枚举。根据问题的最后一句话,停止使用枚举也是一个可行的解决方案。具体来说,可以考虑将枚举替换为其他合适的数据结构或者设计模式来实现相同的功能。
总之,出现(Enum type not defined at runtime)这个问题的原因是在引入重新导出的枚举时出现了错误。为了解决这个问题,可以使用正确的import语句来引入枚举,或者考虑停止使用枚举并使用其他合适的数据结构或设计模式来替代。
在我遇到的未定义的枚举类型问题中,原因是循环引用导致的:
在文件`a.ts`中定义了`export enum A {...}`,
在文件`b.ts`中定义了`export const b = ...`;
在`b.ts`中引入了`import {A} from './a.ts'`,
而在`a.ts`中引入了`import {b} from './b.ts'`。
移除循环引用后,错误消失了。
这个方法对我也起作用了。好奇的是,你是如何想到这个解决方法的呢?
哇!有人知道这是否是预期的行为吗?
这个答案真的救了我的晚上。
直到我看到你的答案之前,今年过得不太顺利——和这个确切的问题纠缠了几个小时——一旦看到这个就在2分钟内解决了——谢谢!