Vyhledávání na webu

javascript - Jak zahrnout globální deklaraci typu souboru v balíčku TypeScript (Node.js)


Pracuji na balíčku, který plánuji veřejně zveřejnit na npmjs. Řekněme mu "textový balíček".

Chtěl bych, aby bylo ve výchozím nastavení při instalaci tohoto balíčku možné přímo importovat soubory .txt a získat správný typ (ihned po instalaci), takto:

import text from './file.txt'

Proměnná text by byla typu string, protože balíček by definoval její typ, použitím něčeho takového (v global.d.ts):

declare module '*.txt' {
    export const text: string;
    export default text;
}

Pokud do svého balíčku zahrnu toto global.d.ts a importuji něco z tohoto balíčku, automaticky získám správný typ při importu souboru .txt.

Ale problém je v tom, že někdy bych jen potřeboval importovat soubor .txt aniž bych importoval cokoli z "text package", a proto jsem se ptal, jestli existuje nějaký způsob, jak při instalaci balíčku nainstalovat globální typ, který nevyžaduje importovat cokoli jiného, aby se typ uplatnil.

Jinými slovy, jakmile nainstalujete můj „txt balíček“, declare module '_.txt' by se zkrátka vztahoval na celý můj projekt.

Existuje vůbec způsob, jak to udělat, nebo by kdokoli, kdo instaluje můj balíček, musel deklarovat svůj vlastní globální typ (např. declarations.d.ts), aby mohl globálně importovat soubory .txt?

Vím, že i když typ importu funguje, bude stále vyžadovat Webpack nebo jiný bundler, aby skutečně fungoval, ale tato otázka je jen o typu.

Odpověď č. 1

pro sloučení globálních typů proveďte následující. vytvořte typescript

  • určete výchozí adresář typů v typeRoots, např. "typeRoots": ["./src/types"].
  • vytvořte soubor /src/types/global.d.ts ve specifikovaném adresáři
  • deklarujte své typy v souboru uvnitř declare global {} a ujistěte se, že máte export {}, pokud ještě nic neexportujete.

Odpověď č. 2

Krátká odpověď je:

TypeScript nepodporuje globální typy bez importování souboru odkazujícího na typ.

Další podrobnosti:

Jedním příkladem, který jsem při tom našel, je Next.js - při vytváření aplikace v TypeScriptu pomocí npx create-next-app@latest --typescript můžete začít importovat soubory *.css (například) a získat správný typ.

Kde jsem se zmátl, je to, že jsem původně myslel, že typ pochází ze souboru next-env.d.ts, ale i když jsem soubor smazal, import *.css stále fungoval ve Visual Studio Code. Ale důvodem bylo to, že soubor v adresáři pages importoval soubor index.d.ts z Next.js.

V zásadě platí, že ve Visual Studio Code, jakmile někde ve svém projektu naimportujete typ, pokud je globální, bude dostupný všude.

Obejití

Co tedy lze udělat se současnými možnostmi TypeScriptu? Pro podporu nových typů souborů budete potřebovat načítací modul souborů, například Webpack. Logickým krokem by bylo přidat odkaz na deklaraci typu souboru přímo do samotného načítacího modulu. Tímto způsobem, jakmile nakonfigurujete svůj načítací modul souborů tak, aby mohl soubor importovat, zdědíte typ:

  1. vytvořte txt.d.ts ve zdrojovém adresáři naší knihovny (např. src) - pro soubor můžete použít libovolný název, není to důležité
  2. pokud používáte eslint, přidejte položku pro ignorování typu souboru (např. 'src/*.d.ts' ve vaší možnosti ignorePatterns
  3. Jelikož přidáváte soubor d.ts do svého zdroje, který není spravován tsc, musíte přidat skript, který provede následující akce:

    1. Zkopírujte txt.d.ts do cílového adresáře zkompilovaných souborů pro váš balíček
    2. Přidejte tento řádek na začátek souboru načítacího modulu vašeho balíčku (např. loader/index.d.ts: /// <reference types="../txt" />\r\n - toto propojí deklarovaný soubor zpět do vašeho balíčku. Všimněte si, že tento odkaz můžete přidat do libovolného souboru vašeho balíčku.

Tento obcházející postup bude fungovat pouze poté, co importujete soubor odkazující zpět na deklaraci - to je jediný způsob, jak může TypeScript poznat, že tento typ existuje (viz https://github.com/microsoft/TypeScript/issues/49124).

Další alternativou by také mohlo být přidat manuální kroky (v souboru readme) pro přidání souboru s deklarací globálního typu.

Související články