我的 Typescript / Ember 3.1 应用程序中有一个枚举,但在运行时出现导入错误。这是怎么回事?

I have an enum in my Typescript / Ember 3.1 app and I am getting import errors at runtime. What's going on?

我有一个 ember 组件正在导入枚举类型,如下所示:

import { StateNames, CardSummary } from '../../types/snowcat/state-types'

类型文件如下:

export enum CardState {
  error = 'error',
  new = 'new',
  okay = 'okay',
  warning = 'warning',
}

然后我在组件中使用枚举如下:

  @computed('cardSummary.cardState')
  get type(): string {
    if ([CardState.new, CardState.okay, CardState.warning].includes(this.cardSummary.cardState)) {
      return 'info'
    }
    return 'error'
  }

代码似乎一切正常。我在构建代码时没有收到任何 TypeScript 错误,但我 收到运行时错误:

loader.js:247 Uncaught Error: Could not find module `types/snowcat/state-types` imported from `snowcat/models/certificate`
    at missingModule (loader.js:247)
    at findModule (loader.js:258)
    at Module.findDeps (loader.js:168)
    at findModule (loader.js:262)
    at requireModule (loader.js:24)
    at r (loader.js:176)
    at ember-data.js:39
    at Array.forEach (<anonymous>)
    at getDsModels (ember-data.js:36)
    at getModels (ember-data.js:66)

这是怎么回事?我该如何解决这个问题?

这是因为 types 模块未包含在 ember-cli-typescript 的 编译 中。纯类型声明可以正常工作,因为它们在 compile-time 处被删除。然而,enums have runtime representations, not just compile-time representations—unlike pretty much everything else in TypeScript! (You can sometimes work around that with const enum 类型代替,但它们有自己的权衡。)

在任何情况下,因为 ember-cli-typescript 默认情况下不包括 types 编译目录——仅用于类型解析——结果是您可以将枚举用作 type 但你不能使用它们从中实际创建一个值,这在很大程度上违背了这一点。

最好的做法是为仅声明存在于您的应用程序外部的类型或在您的应用程序中没有运行时表示的常见类型保留 your-app/types/,并放置具有与之关联的运行时功能的类型他们在 your-app/app/lib 之类的地方。然后,您可以从任何模块中导出类型,并像往常一样在整个应用程序中重复使用它们。

或者,您可以将 types 添加到 tsconfig.json"paths" 列表中,但这可能会让开始处理您的 ember-cli-typescript 的其他用户感到惊讶应用!