最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to use enum from typescript definition file? - Stack Overflow

programmeradmin1浏览0评论

I'm programming in nodejs using typescript.

I'm using pdfmake and I installed typescript definition files for this library (@types/pdfmake)

.d.ts

I'm importing one of the enums from this file

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

and using it like this PageSize.A4

This compiles, but when I try to access value A4 of this enum, runtime error occurs

TypeError: Cannot read property 'A4' of undefined

Any help would be greatly appreciated

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"]
}```

I'm programming in nodejs using typescript.

I'm using pdfmake and I installed typescript definition files for this library (@types/pdfmake)

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

I'm importing one of the enums from this file

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

and using it like this PageSize.A4

This compiles, but when I try to access value A4 of this enum, runtime error occurs

TypeError: Cannot read property 'A4' of undefined

Any help would be greatly appreciated

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"]
}```
Share Improve this question edited Sep 3, 2019 at 14:40 displayName asked Sep 3, 2019 at 14:06 displayNamedisplayName 1,1062 gold badges16 silver badges41 bronze badges 1
  • Please include your package.json and tsconfig into question. – mayakwd Commented Sep 3, 2019 at 14:17
Add a comment  | 

3 Answers 3

Reset to default 11 +25

The problem is that type definitions are just for types. They don't change the runtime behavior of a module. So while TypeScript is happy with your code because the type definitions say that this module exports an enum PageSize, this falls apart when running the code because in reality the module does not export PageSize.

I would consider this a bug in @types/pdfmake.

This problem could be resolved in @types/pdfmake by making the enum const:

const enum PageSize {
   // ...
}

TypeScript automatically inlines const enums. Inlining means the compiler replaces PageSize.A4 with 'A4' so that there are no references to PageSize left in the JavaScript code.

Of course this would require a change in @types/pdfmake. I encourage you to open a pull request or issue on the DefinitelyTyped repo.


Without any changes in @types/pdfmake the only option you have is use hardcoded strings:

pageSize: 'A4' as PageSize

Unfortunately you'll probably even have to cast it to the PageSize enum, because that's what the type definitions expect.

When processing an enum in a TypeScript source file (.ts), the TypeScript compiler emits the appropriate JavaScript code to create an object which can be accessed at runtime.

However when processing the TypeScript declaration file (.d.ts) in your case, the enum is has been wrapped inside a declare module "pdfmake/build/pdfmake" block. Inside a "declare module", the compiler does not try to implement the object. Compare example 1 vsexample 2 on the TypeScript playground to understand the effect.

This behavior is by design, because the intended use-case for declaration files is enable type-checking of code written in a separate module (typically one written in JavaScript.)

Let me know if that isn't clear.

First your import is incorrect as pdfmake/build/pdfmake has no default export. You can use:

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

to get a reference to the module, but you will find that the module has no reference to the PageSize enum as it wasn't exported as Burt_Harris explained in his answer.

发布评论

评论列表(0)

  1. 暂无评论