O "*.d.ts" u TypeScriptu


Zanima me .d.ts datoteke deklaracija. Netko mi je rekao da su .d.ts datoteke slične .h zaglavnim datotekama u programskim jezicima C i C++, međutim, čini se da .d.ts datoteke ne funkcioniraju potpuno na isti način. Trenutno ne uspijevam razumjeti kako pravilno koristiti .d.ts datoteke.

Izgleda da ne mogu dodati svoje .js ili .ts datoteke u .d.ts datoteke, pa jedini način da moj projekt radi je ako sadrži sve tri vrste datoteka. Moja pitanja su:

  1. Kakav je odnos između ta tri datoteke?

  2. Kako mogu koristiti *.d.ts datoteku, znači li to da mogu trajno izbrisati *.ts datoteku?

  3. Ako je tako, kako *.d.ts datoteka može znati koja JS datoteka se mapira na nju?

Odgovor #1

Datoteka "d.ts" se koristi za pružanje TypeScript informacija o tipovima za API koji je napisan u JavaScriptu. Ideja je da koristite nešto poput jQueryja ili Underscorea, postojeće JavaScript biblioteke. Želite ih koristiti u svom TypeScript kodu.

Umjesto da prepisujete jquery ili underscore ili što već u Typescriptu, možete umjesto toga napisati d.ts datoteku, koja sadrži samo oznake tipova. Tada iz vašeg Typescript koda dobivate prednosti statičkog provjeravanja tipova dok i dalje koristite čistu JS biblioteku.

Ovo funkcionira zahvaljujući TypeScriptovom ograničenju da vam ne dopušta dodavanje ekstenzije ".ts" na kraj import naredbe. Zbog toga, kada referencirate neku datoteku, recimo, my-module.js, ako se pored nje nalazi my-module.d.ts, TypeScript će uključiti njen sadržaj:

src/
  my-module.js
  my-module.d.ts
  index.ts

my-module.js

const thing = 42;

module.exports = { thing };

my-module.d.ts

export declare const thing: number;

index.ts

import { thing } from "./my-module"; // <- no extension

// runtime implementation of `thing` is taken from ".js"
console.log(thing); // 42

// type declaration of `thing` is taken from ".d.ts"
type TypeOfThing = typeof thing; // number

Odgovor #2

d označava datoteke deklaracija:

Kada se TypeScript skripta kompajlira, postoji opcija za generiranje deklaracijske datoteke (s ekstenzijom .d.ts) koja funkcionira kao sučelje za komponente u kompajliranom JavaScriptu. U tom procesu kompajler uklanja sve tijela funkcija i metoda, a čuva samo potpise tipova koji se izvoze. Dobivena deklaracijska datoteka se zatim može koristiti za opis izvoženih virtualnih TypeScript tipova JavaScript biblioteke ili modula kada ih treća strana koristi iz TypeScripta.

Koncept datoteka deklaracija analogn je konceptu zaglavnih datoteka koje se nalaze u C/C++.

declare module arithmetics {
    add(left: number, right: number): number;
    subtract(left: number, right: number): number;
    multiply(left: number, right: number): number;
    divide(left: number, right: number): number;
}

Datoteke s deklaracijama tipova mogu se pisati ručno za postojeće JavaScript biblioteke, kao što je učinjeno za jQuery i Node.js.

Velike zbirke deklaracijskih datoteka za popularne JavaScript biblioteke nalaze se na GitHubu u CertainlyTyped i Typings Registryju. Komandna linija utiliteta zvana typings pruža se kako bi pomogla u pretraživanju i instaliranju deklaracijskih datoteka iz repozitorija.

Odgovor #3

Naučio sam sljedeće iz potrebe da mukotrpno mapiram JavaScript projekt koristeći .d.ts datoteke.

Korištenje .d.ts datoteke za mapiranje JavaScripta zahtijeva da svoje .d.ts datoteke imenujete isto kao i svoje .js datoteke. Svaka .js datoteka mora biti zadržana u istoj mapi (držeći se u istom direktoriju) s .d.ts datotekom koja ima isto ime. Uputite JS/TS kod koji treba tipove iz .d.ts datoteka na te .d.ts datoteke.

npr.: test.js i test.d.ts su u mapi testdir/, tada ih u react komponenti uvozite na sljedeći način:

import * as Test from "./testdir/test";

Datoteka .d.ts je izvezena kao prostor imena na sljedeći način:

export as namespace Test;
    
export interface TestInterface1{}
export class TestClass1{}

Odgovor #4

Primjer rada za specifičan slučaj:

Recimo da imate my-module koji dijelite putem npm.

Instalirate ga s npm install my-module

Koristite ga ovako:

import * as lol from 'my-module';

const a = lol('abc', 'def');

Cijela logika modula je u index.js:

module.exports = function(firstString, secondString) {

  // your code

  return result
}

Za dodavanje tipova, stvorite datoteku index.d.ts:

declare module 'my-module' {
  export default function anyName(arg1: string, arg2: string): MyResponse;
}

interface MyResponse {
  something: number;
  anything: number;
}

Odgovor #5

Kao što je @takeshin rekao, .d označava datoteku deklaracije za TypeScript (.ts).

Nekoliko točaka koje treba razjasniti prije nego što nastavimo s odgovorom na ovu objavu -

  1. Typescript je sintaktički nadskup JavaScripta.
  2. Typescript ne radi samostalno, mora se transpilirati u JavaScript (konverzija iz Typescripta u JavaScript)
  3. "Definicija tipa" i "Provjera tipa" su glavne dodatne funkcionalnosti koje TypeScript pruža u odnosu na JavaScript. (provjerite razliku između TypeScript i JavaScript)

Ako razmišljate je li TypeScript samo sintaktički nadskup, koje prednosti nudi - https://basarat.gitbooks.io/typescript/docs/why-typescript.html#the-typescript-type-system

Za odgovor na ovu objavu -

Kao što smo razgovarali, TypeScript je nadskup JavaScripta i treba ga transpajlirati u JavaScript. Dakle, ako je biblioteka ili tuđi kod napisan u TypeScriptu, on se na kraju pretvara u JavaScript koji se može koristiti u JavaScript projektu, ali obrnuto ne vrijedi.

Na primjer -

Ako instalirate JavaScript biblioteku -

npm install --save mylib

i pokušajte ga uvesti u TypeScript kod -

import * from "mylib";

dobit ćete pogrešku.

"Ne može se pronaći modul 'mylib'."

Kao što je spomenuo @Chris, mnoge biblioteke poput underscorea i Jqueryja već su napisane u JavaScriptu. Umjesto da se te biblioteke ponovno pišu za TypeScript projekte, bila je potrebna alternativa.

Kako biste to učinili, možete pružiti datoteku s deklaracijom tipa u JavaScript biblioteci nazvanu *.d.ts, poput gore navedenog slučaja mylib.d.ts. Datoteka deklaracije pruža samo deklaracije tipova funkcija i varijabli definiranih u odgovarajućoj JavaScript datoteci.

Sada kada pokušaš -

import * from "mylib";

mylib.d.ts se uvozi što djeluje kao sučelje između JavaScript biblioteke i TypeScript projekta.

Odgovor #6

Ovaj odgovor pretpostavlja da imate neki JavaScript koji ne želite pretvoriti u TypeScript, ali želite iskoristiti provjeru tipova uz minimalne promjene u vašoj .js datoteci. .d.ts datoteka je vrlo slična C ili C++ zaglavnoj datoteci. Njezina svrha je definirati sučelje. Evo primjera:

mashString.d.ts

/** Makes a string harder to read. */
declare function mashString(
    /** The string to obscure */
    str: string
):string;
export = mashString;

mashString.js

// @ts-check
/** @type {import("./mashString")} */
module.exports = (str) => [...str].reverse().join("");

main.js

// @ts-check
const mashString = require("./mashString");
console.log(mashString("12345"));

Odnosi ovdje su: mashString.d.ts definira sučelje, mashString.js implementira sučelje i main.js koristi sučelje.

Da bi provjera tipova radila, dodajte // @ts-check u svoje .js datoteke. No to provjerava samo da main.js ispravno koristi sučelje. Da bismo također osigurali da ga mashString.js ispravno implementira, dodajemo /** @type {import("./mashString")} */ prije izvoza.

Možete stvoriti svoje početne .d.ts datoteke koristeći tsc -allowJs main.js -d, a zatim ih po potrebi ručno uređivati kako biste poboljšali provjeru tipova i dokumentaciju.

U većini slučajeva implementacija i sučelje imaju isto ime, ovdje mashString. Ali možete imati alternativne implementacije. Na primjer, mogli bismo preimenovati mashString.js u reverse.js i imati alternativni encryptString.js.

Povezani članci