我有一个问题,其中Typescript编译器成功编译了我的代码,但运行时给了我未定义的类型错误。
在我的应用程序中,我创建了一个types.ts
文件,其中包含多个其他ts文件之间共享的内容。它包含一个字符串枚举,如:
enum MyEnum {
One = "one";
Two = "two";
}
当我这样定义它时。编译器让我在其他ts文件中使用它,看起来很开心。但是,在运行时我收到错误“MyEnum未定义”。
我知道有两种方法可以解决这个问题:
我对Typescript很新,我觉得我可能会误解一些基本的东西。
首先,我不明白为什么如果会出现运行时错误,Typescript编译器会愉快地编译我的代码。如果我使用declare
关键字告诉编译器 应该在运行时可用,我会理解它,但在这种情况下我不明白为什么它应该假设枚举来自其他任何地方,然后是types.ts文件。
其次,我想在我的应用程序中全局定义类型,并让它们在任何地方都可用,而不必在每次使用它们时都导入它们。我该如何做到这一点?或者这可能被认为是不好的做法?
我正在使用Typescript 2.6,我的配置如下所示:
{
"compilerOptions": {
/* Basic Options */
"target": "es6",
"module": "commonjs",
"lib": ["es6", "es7", "esnext"],
"sourceMap": true /* Generates corresponding '.map' file. */,
"outDir": "build" /* Redirect output structure to the directory. */,
"removeComments": true /* Do not emit comments to output. */,
/* Strict Type-Checking Options */
"strict": true /* Enable all strict type-checking options. */,
/* Additional Checks */
"noUnusedLocals": true /* Report errors on unused locals. */,
"noUnusedParameters": true /* Report errors on unused parameters. */,
"noImplicitReturns": true /* Report error when not all code paths in function return a value. */,
"noFallthroughCasesInSwitch": true /* Report errors for fallthrough cases in switch statement. */,
"plugins": [{ "name": "tslint-language-service" }],
"skipLibCheck": true // because firebase-sdk has wrong type files now (Nov 18)
},
"include": ["src/**/*"],
"exclude": ["build"]
}
答案 0 :(得分:10)
还有另一种方法可以做到这一点。如果您不想导出枚举,可以将其定义为 const enum
const enum MyEnum {
One = "one";
Two = "two";
}
这些内容由编译器内联,并在编译期间完全删除。
答案 1 :(得分:3)
我有这个问题,因为我使用了声明
export declare enum SomeEnum
代替
export enum SomeEnum
答案 2 :(得分:2)
当导入重新导出枚举时,我遇到了同样的问题。它导致运行时错误。
layout.ts
export enum Part { Column, Row }
index.ts
export * from './layout'
component.ts
import { Part } from '../entities' // This causes error
import { Part } from '../entities/layout' // This works
答案 3 :(得分:1)
在我的matrix
枚举中,事实证明是由于循环导入:
vector
中定义的 c
,
NA
在文件na.omit
中定义;
lst1 <- sapply(split(v1, sign(v1)), function(x)
x[order(abs(x), decreasing = TRUE)])[2:1]
c(na.omit(c(do.call(rbind, lapply(lst1, `length<-`, max(lengths(lst1)))))))
#[1] 3.0 -5.0 1.5 -0.6 1.0 -0.5 0.7
在v1 <- c(-0.5, -0.6, 0.7, 1, 1.5, 3, -5)
中,
而undefined
中的export enum A {...}
。
删除循环导入后错误消失了。
答案 4 :(得分:0)
我遇到了这个错误,一旦我使用了export关键字,它就会消失,即
export enum MyEnum {
One = "one";
Two = "two";
}
并确保将其导入到您正在使用它的文件中,即
import { MyEnum } from '../types.ts';
我发现当我在没有export关键字的情况下声明枚举时,我仍然可以在没有编译器错误的情况下引用枚举而不将其导入其他文件中 - 只是在运行时才会抛出未定义的异常。
答案 5 :(得分:0)
这是我的情况,当我向enum.ts
文件中添加一个新的枚举像这样时:
enum.ts
:
enum RotateMode {
UNKNOWN = 'UNKNOWN',
OPTIMIZE = 'OPTIMIZE',
ROTATE_FOREVER = 'ROTATE_FOREVER'
}
export { RotateMode };
我没有运行tsc
来再次编译该文件。这导致enum.js
文件没有RotateMode
枚举
enum.js
:
// old file doesn't have the RotateMode enum
然后,将RotateMode
枚举导入到我的index.ts
文件中:
import { RotateMode } from './enum';
console.log(`RotateMode: ${JSON.stringify(RotateMode)}`);
结果是:
RotateMode: undefined
以某种方式,import
语法将优先导入.js
文件
因此,添加新内容后不要忘记编译ts文件
答案 6 :(得分:0)
对于我们来说,事实证明,只需重新启动应用程序即可解决问题。 (Nativescript应用)
答案 7 :(得分:0)
我可能会迟到,但要注意错误堆栈归咎于文件中的任何 @ts-ignore 行。
我的问题是,经过相当大的重构后,导入到枚举的内容被 IDE 快捷方式清除,编译器无法检测到它丢失,因为 ts-ignore 注释是针对其他内容的(唉, 在同一行)。
答案 8 :(得分:-1)
export enum Expertlavel {
Beginner = 0,
Intermediate = 10,
Expert = 20
};
-导出所有枚举
export * from "../Enums/enums";