javascript - Hvordan bruke enum fra en TypeScript-definisjonsfil?
Jeg programmerer i Node.js ved hjelp av TypeScript.
Jeg bruker pdfmake, og jeg har installert TypeScript-definisjonsfiler for dette biblioteket (@types/pdfmake)
https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/pdfmake/index.d.ts
Jeg importerer en av enumene fra denne filen
import { PageSize } from "pdfmake/build/pdfmake";og bruke det slik PageSize.A4
Dette kompilerer, men når jeg prøver å få tilgang til verdien A4 av denne enumen, oppstår en kjøretidsfeil
TypeError: Kan ikke lese egenskapen 'A4' av undefined
Enhver hjelp ville blitt høyt verdsatt
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"]
}```
Svar #1
Problemet er at typedefinisjoner kun er for typer. De endrer ikke kjøretidsatferden til en modul. Så selv om TypeScript er fornøyd med koden din fordi typedefinisjonene sier at denne modulen eksporterer en enum PageSize, går dette i stykker når koden kjører fordi modulen i realiteten ikke eksporterer PageSize.
Jeg vil anse dette som en feil i @types/pdfmake.
Dette problemet kunne løses i @types/pdfmake ved å gjøre enumen const:
const enum PageSize {
// ...
}
TypeScript legger automatisk inn const-enum. Å legge inn betyr at kompilatoren erstatter PageSize.A4 med 'A4' slik at det ikke er noen referanser til PageSize igjen i JavaScript-koden.
Selvfølgelig ville dette kreve en endring i @types/pdfmake. Jeg oppfordrer deg til å åpne en pull request eller issue på DefinitelyTyped-repoen.
Uten noen endringer i @types/pdfmake er det eneste alternativet du har å bruke hardkodede strenger:
pageSize: 'A4' as PageSize
Dessverre må du sannsynligvis til og med kaste det til PageSize-enum, fordi det er det type-definisjonene forventer.
Svar #2
Når man behandler en enum i en TypeScript kildefil (.ts), genererer TypeScript-kompilatoren den passende JavaScript-koden for å lage et objekt som kan aksesseres under kjøring.
Men når du behandler TypeScript deklarasjonsfilen (.d.ts) i ditt tilfelle, er enum-en pakket inn i en declare module "pdfmake/build/pdfmake"-blokk. Inne i en "declare module" prøver ikke kompilatoren å implementere objektet. Sammenlign eksempel 1 med eksempel 2 på TypeScript playground for å forstå effekten.
Denne oppførselen er designet slik, fordi den tiltenkte bruken av deklarasjonsfiler er å muliggjøre typekontroll av kode skrevet i en separat modul (vanligvis en skrevet i JavaScript).
Gi meg beskjed hvis det ikke er klart.
