Search code examples
javascriptnode.jstypescripttypescript-typingspdfmake

How to use enum from typescript definition file?


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

Solution

  • 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.