Vyhledávání na webu

Psání souboru s deklaracemi TypeScriptu pro externí balíček JS Node.js, bez informací o typech


Píšu knihovnu v Node.js s TypeScriptem (pro použití v kontextu CLI aplikace), která má závislost na JS knihovně jinxed, která nemá TypeScriptové deklarace typů. Sleduji informace o souborech deklarací TypeScriptu.

jinxed je jednoduchá knihovna, která momentálně exportuje jedinou funkci přes module.exports { ... }, není určena být jediným exportem z knihovny (protože bude v budoucnu rozšířena). Takže exportovaná funkce je členem exportovaného objektu.

Problém je, jak to spotřebovat v knihovně TypeScript. Po přečtení všech dokumentací k deklaracím TypeScript mi stále není jasné, jak to udělat.

Prvním problémem, který je třeba vyřešit, je, který šablonový deklarace vybrat ze šablon souborů deklarací Typescript.

Rozhodl jsem se, že vhodnou šablonou pro umožnění používání jinxed z TypeScriptu je module.d.ts (nicméně mohu se mýlit).

Tak moje klientská knihovna TypeScript (widget) vypadá takto:

widget/
  lib/
    externalTypes/
      jinxed/
        index.d.ts
    index.ts

Takže výše mi ukazuje, jak definuji typový soubor pro externí závislost jinxed podle pokynů v šablonovém souboru; tj. vytvořit složku, jejíž název odpovídá názvu externí závislosti, a vložit do ní soubor index.d.ts.

widget/lib/externalTypes/jinxed/index.d.ts:

exportovat funkci functify(obj: any): string;

Na straně spotřeby; tj. uvnitř mého souboru index.ts (widget/lib/index.ts):

/// <reference types="./externalTypes/jinxed" />

import jinxed = require('jinxed');

const TestObject:any = {
  name: 'dvorak',
  occ: 'watchman'
};

jinxed.functify(TestObject);

[PS: Také jsem zkusil:

let jinxed=require('./externalTypes/jinxed'); ( ... ale to jen vede k chybě ohledně použití příkazu require)

]

Ale při kompilaci se objeví následující chybová zpráva:

CHYBA v /Users/User/dev/github/js/widget/lib/index.ts ./lib/index.ts [tsl] CHYBA v

/Users/User/dev/github/js/widget/lib/index.ts(4,25) TS7016: Nepodařilo se najít deklaraci souboru pro modul 'jinxed'. '/Users/User/dev/github/js/widget/node_modules/jinxed/index.js' má implicitně typ 'any'.

(Omlouváme se za to, že chybová zpráva vypadá trochu ošklivě, problémy s formátováním)

[

A pro úplnost je obsah slova 'jinxed' následující:

'use strict';

function functify (obj) {
  return JSON.stringify(obj, (key, val) => {
    return (typeof val === 'function') ? '_function_' : val;
  });
}

module.exports = {
  functify: functify
}

]

Chybová zpráva uvádí, že nemůže najít deklaranční soubor pro jinxed, ale já jsem použil

 /// <reference...

abych určil typ souboru, který se má použít, takže nevím, v čem je problém.

Závislosti v souboru widget package.json jsou následující:

  "dependencies": {
    "@types/ramda": "^0.26.19",
    "jinxed": "0.0.1",
    "ramda": "^0.26.1",
    "xpath": "0.0.27"   },

Soubor tsconfig je:

{
  "compilerOptions": {
    "allowJs": true,
    "alwaysStrict": true,
    "module": "commonjs",
    "moduleResolution": "Node",
    "noImplicitAny": true,
    "sourceMap": true,
    "strictNullChecks": true,
    "target": "es5",
    "types": [],
    "lib": [
      "es5",
      "es2015",
      "es6",
      "dom"
    ]
  },
  "include": [
    "lib/**/*"
  ],
  "exclude": [
    "node_modules",
    "**/*.spec.ts"
  ]
}

Hlavní položka v souboru package.json je:

"main": "./lib/index.ts",

Také bych chtěl vědět, zda se způsob, jak jsem strukturoval externí typové závislosti, zdá rozumný. Tedy, řekněme, že se snažím využít další externí knihovnu js podobným způsobem, jak je uvedeno výše pro jinxed; předpokládal bych, že vytvořím další složku pod externalTypes, která odpovídá názvu té závislosti, a naplním ji vlastním index.d.ts. Je to správně, nebo jdu špatným směrem?

UPRAVIT: (Našel jsem řešení tohoto problému přes tento problém, ale opravdu tomu nerozumím.

V souboru index.d.ts jsem jej aktualizoval takto:

declare module 'jinxed' {
  export function functify(obj: any): string;
}

... a to skutečně funguje.

Avšak nerozumím příkazu declare module, zejména proč je název jinxed uvnitř uvozovek (když uvozovky odstraníte, dostanete chybu: TS7016: Nebyla nalezena deklarace souboru pro modul 'jinxed'). Zatím jsem nenašel správnou šablonu TypeScriptu, která by tomu odpovídala, takže nemohu získat dobré vysvětlení, proč to funguje.

Odpověď č. 1

Vypadá to, že jste našli odpověď na svou původní otázku, ale myslel jsem, že se podělím o některé zdroje týkající se vaší druhé otázky. Z dokumentace TypeScriptu: Ambientní moduly

V Node.js se většina úloh provádí načtením jednoho nebo více modulů. Každý modul bychom mohli definovat ve svém vlastním souboru .d.ts s deklaracemi exportu na nejvyšší úrovni, ale je pohodlnější napsat je jako jeden větší soubor .d.ts. K tomu používáme konstrukci podobnou ambientním jmenným prostorům, ale používáme klíčové slovo module a uvedené jméno modulu, který bude později dostupný pro import.

declare module jsou klíčová slova jazyka a řetězec je název modulu, který importujete.

Související články