Zoeken op website

node.js - Typescript: Type importeren uit pakket zonder afhankelijkheden van andere types in hetzelfde pakket


Ik heb een NPM-pakket geschreven in Typescript (laten we het libd noemen) dat enkele klassen en types aanbiedt. Ze worden geëxporteerd in een index.ts-bestand zoals dit:

export { ClassA } from "./ClassA";
export { TypeB } from "./TypeB";

De ClassA gebruikt een externe afhankelijkheid (laten we het depc noemen) die is ingesteld als peerDependencies in de package.json. De TypeB is slechts een type zonder externe afhankelijkheden.

In het package.json bestand is het main-veld ingesteld op dist/index.js (waar het naartoe is getranspileerd) en types zijn ingesteld op dist/index.d.ts.

Het tsconfig.json van het libd-pakket ziet er zo uit:

{
  "compilerOptions": {
    "target": "ES2019", 
    "module": "commonjs",
    "declaration": true,
    "outDir": "dist",
    "rootDir": "src",
    "inlineSources": true,
    "inlineSourceMap": true
  }
}

Nu gebruik ik TypeB in een andere bibliotheek (laten we het libe noemen) zonder ClassA te importeren en zonder de depc-afhankelijkheid geïnstalleerd te hebben. De libd-bibliotheek is geïnstalleerd via NPM en het type wordt als volgt geïmporteerd:

import { TypeB } from "libd";

De tsconfig.json van libe is vergelijkbaar met die van libd.

Het transpilen hiervan geeft me de fout TS2307: Kan module 'depc' niet vinden.

Nu begrijp ik het, als ik ClassA zou gebruiken, moet ik depc installeren omdat het dat importeert. Maar ik gebruik alleen TypeB dat geen afhankelijkheden vereist en soms worden types meegeleverd met het originele pakket.

Ik zou dit probleem kunnen oplossen door @types/depc te installeren en Typescript zou blij zijn. De code zou moeten werken tijdens runtime, aangezien er geen daadwerkelijk gebruik van depc komt vanuit libe. Maar ik zou liever geen nutteloze pakketten installeren.

Het instellen van "skipLibCheck": true in de tsconfig.json van libe zou de tsc-fout ook oplossen, maar ik weet niet zeker welke negatieve effecten dit zou hebben.

Dus mijn vraag is: Waarom controleert TypeScript een klasse van een dependency die ik niet importeer? Is het omdat ik alle exports van het libd-pakket heb gebundeld in een index.ts-bestand en alle imports daarvan via dit indexbestand lopen?

Kan ik dit oplossen zonder TypeB en ClassA in verschillende pakketten te splitsen? Dat zou ze erg kleine pakketten maken en ongeveer 80% van de tijd zouden ze allebei geïnstalleerd zijn.

Antwoord #1

Is het omdat ik alle exports van het libd pakket in een index.ts bestand heb gebundeld […]?

Ja.

De TypeScript-compiler ziet dat je het bestand libd/dist/index.{js|d.ts} gebruikt en begint de exports ervan te evalueren. Terwijl dit gebeurt, ontdekt het dat ClassA depc gebruikt, en gaat het depc evalueren - maar het is nergens te vinden (omdat het niet geïnstalleerd is). Dat is een definitieve fout.

De TypeScript-compiler controleert niet of je ClassA gebruikt of niet, het is niet zijn taak om tree shaking uit te voeren.

Het gebruik van "skipLibCheck": true is eigenlijk een goede manier om dit probleem op te lossen, aangezien de beschrijving expliciet vermeldt:

In plaats van een volledige controle van alle d.ts-bestanden uit te voeren, zal TypeScript de code typecontroleren waar je specifiek naar verwijst in de broncode van je app.

… wat uiteindelijk is wat je wilt, toch?

Gerelateerde artikelen