如何使用打字稿定义文件中的枚举?

How to use enum from typescript definition file?

我正在使用 typescript 在 nodejs 中编程。

我正在使用 pdfmake 我为这个库安装了打字稿定义文件 (@types/pdfmake)

https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/pdfmake/index.d.ts

我正在从该文件中导入枚举之一

import { PageSize } from "pdfmake/build/pdfmake";

并像这样使用它PageSize.A4

这可以编译,但是当我尝试访问此枚举的值 A4 时,发生运行时错误

TypeError: 无法读取未定义的 属性 'A4'

如有任何帮助,我们将不胜感激

package.json:

{
  "name": "nodejs-pdf-make",
  "version": "1.0.0",
  "description": "",
  "main": "dist/app.js",
  "scripts": {
    "start": "tsc && node --inspect dist/app.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@types/express": "^4.17.1",
    "tslint": "^5.19.0",
    "typescript": "^3.6.2"
  },
  "dependencies": {
    "@types/pdfmake": "^0.1.8",
    "express": "^4.17.1",
    "pdfmake": "^0.1.58"
  }
}

tsconfig.json:

{
  "compilerOptions": {
    "module": "commonjs",
    "esModuleInterop": true,
    "target": "es6",
    "moduleResolution": "node",
    "sourceMap": true,
    "outDir": "dist"
  },
  "lib": ["es2015"]
}```

问题是类型定义只针对类型。它们不会改变模块的运行时行为。因此,虽然 TypeScript 对您的代码很满意,因为类型定义表明此模块导出一个枚举 PageSize,但当 运行 代码时,这会分崩离析,因为实际上模块不会导出 PageSize

我认为这是 @types/pdfmake 中的错误。

这个问题可以在 @types/pdfmake 中解决,方法是使枚举 const:

const enum PageSize {
   // ...
}

TypeScript 自动内联 const 枚举。内联意味着编译器将 PageSize.A4 替换为 'A4',这样就不会在 JavaScript 代码中留下对 PageSize 的引用。

当然这需要在 @types/pdfmake 中进行更改。我鼓励您在 DefinitelyTyped repo.

上打开拉取请求或问题

@types/pdfmake 中没有任何更改,您唯一的选择是使用硬编码字符串:

pageSize: 'A4' as PageSize

不幸的是,您甚至可能不得不将其转换为 PageSize 枚举,因为这是类型定义所期望的。

在 TypeScript 源文件 (.ts) 中处理 enum 时,TypeScript 编译器发出适当的 JavaScript 代码来创建一个对象可以在运行时访问。

然而,在处理 TypeScript 声明文件 (.d.ts) 时,enum 已被包裹在 declare module "pdfmake/build/pdfmake" 堵塞。在 "declare module" 内部,编译器不会尝试实现该对象。在 TypeScript 操场上比较 example 1 vsexample 2 以了解效果。

此行为是设计使然,因为声明文件的预期用例是启用对在单独模块中编写的代码(通常是在 JavaScript 中编写的代码)进行类型检查

如果不清楚,请告诉我。

首先,您的导入不正确,因为 pdfmake/build/pdfmake 没有默认导出。 您可以使用:

import * as pdfMake from "pdfmake/build/pdfmake";

获取对该模块的引用,但您会发现该模块没有对 PageSize 枚举的引用,因为它没有按照 Burt_Harris 在他的回答中解释的那样导出。