javascript - Hvordan eksporterer jeg flere interfaces på en indlejret måde i TypeScript?


Jeg har et ret stort npm-modul skrevet i TypeScript, som eksponerer en række typer, inklusive flere interfaces. Nu giver disse interfaces ikke alle mening på rotniveau, hvilket er grunden til, at jeg gerne vil eksponere dem på en måde, så de kan importeres på en noget indlejret måde.

Grundlæggende leder jeg efter en måde at eksponere interface på, så brugeren af modulet kan gøre:

import { Foo } from 'my-module';
import { Bar } from 'my-module/sub-part';

Er dette muligt i TypeScript, og hvis ja, hvordan? Hvad der ikke virker, er denne kode i rodfilen index.ts:

export {
  Foo,
  { Bar }
};

Bemærk venligst, at .ts-filerne ikke er placeret i modullets rodmappe, og derfor er .js- og .d.ts-filerne det heller ikke.

Hvordan kan jeg løse dette?

PS: Det handler ikke om standard- vs navngivet eksport her, da jeg vil have en løsning til at eksportere interfaces i flere indlejrede niveauer.

Svar #1

I det nemmeste tilfælde har du blot separate index.d.ts-filer inde i my-module og my-module/sub-part-mappen i den udgivne npm-pakke, så vi kan importere my-module og my-module/sub-part separat. Eksempel på projektmappe:

my-module
|   dist
│   index.ts
│   package.json // types prop e.g. could point to dist/index.d.ts
│
└───sub-part
        index.ts // compiled to dist/sub-part/index.d.ts

TS bruger sin modulopløsningsproces til at løse my-module eller my-module/sub-part imports (givet at der ikke findes nogen global typeerklæring som @types). For eksempel løses my-module i import { Foo } from 'my-module' på denne måde:

// first, try to find file directly
node_modules/my-module.ts
node_modules/my-module.tsx
node_modules/my-module.d.ts

// look in package.json for types property pointing to a file
node_modules/my-module/package.json // <-- lands here, if "types" prop exists

// look in @types
node_modules/@types/my-module.d.ts

// treat my-module as folder and look for an index file
node_modules/my-module/index.ts
node_modules/my-module/index.tsx
node_modules/my-module/index.d.ts // <-- lands here otherwise

For fuldstændighedens skyld her, my-module og my-module/sub-part kunne også defineres som separate globale moduldeklarationer i en indeholdende fil, som:

declare module "my-module" {
  const Foo: string
}

declare module "my-module/sub-part" {
  const Bar: number
}

Endelig ser klientkoden ud, som du allerede forestillede dig:

import { Foo } from "my-module";
import { Bar } from "my-module/sub-part";

console.log(Foo)

Håber, det hjælper.

Relaterede artikler