Navnerom vs moduler vs typer i TypeScript?
Kan noen vennligst forklare forskjellen mellom disse konseptene med et eksempel, jeg er virkelig forvirret, hva er vitsen med å ha tre av dem når de alle tjener samme formål?
Svar #1
Kort fortalt
Moduler og navneområder er to former for innkapsling - å dele opp koden din i deler som gir mening. Ny kode bør skrives med moduler, snarere enn navneområder.
Deklarasjonsfiler ("typings") brukes til å beskrive moduler, navnerom, variabler, typedeklarasjoner osv. uten å faktisk inneholde kjørbar kode. Deklarasjonsfiler forteller bare TypeScript hvilke ting som eksisterer, og hvordan du kan bruke disse tingene.
DefinitelyTyped tilbyr deklarasjonsfiler for forskjellige pakker. Deklarasjonsfiler for en DefinitelyTyped-pakke kalt foo-bar vil bli publisert som @types/foo-bar på npm.
Navnerom
Disse formaliserte et noe foreldet mønster i JavaScript. Mønsteret var i hovedsak å pakke kode inn i en IIFE for å forhindre konflikter med deklarasjoner i det globale området. Disse tingene la til «exports» på et objekt og tildelte dem til en variabel som (forhåpentligvis) hadde et unikt navn i det globale området, som $ eller _ eller hva som helst.
Som et eksempel:
namespace foo {
export var x = 10;
export var y = 20;
}
Dette avgir
var foo;
(function (foo) {
foo.x = 10;
foo.y = 20;
})(foo || (foo = {}));
Navneområder har andre nyttige egenskaper, som å kunne slå seg sammen med funksjoner, klasser eller andre navneområder. Men hovedsakelig ble de introdusert i en overgangsperiode hvor det var nødvendig å betjene begge de viktigste måtene å organisere kode på: enten ved å tilby API-overflaten på en godt kjent variabel i det globale området (f.eks. $, _, angular) eller...
Moduler
Disse beskriver alle på en gang ECMAScript (standard JavaScript), CommonJS (dvs. Node.js), AMD (dvs. Require.js) og System.js-moduler. Kjernen i ideen her er at i stedet for bare å plassere variabler i det globale området og håpe de ikke konflikter, får hver fil sitt eget unike område og har eksport.
I praksis fungerer de opprinnelige implementeringene av moduler (CommonJS, AMD, System.js) på samme måte: pakk koden din inn i en funksjon for å få riktig omfang, og fest egenskaper til et objekt.
Men TypeScript lar deg skrive kode som om du skrev ECMAScript-moduler med toppnivå export-setninger. I hovedsak, for TypeScript, er enhver fil med toppnivå import-er eller export-er en modul.
Som et eksempel, følgende
export var x = 10;
export var y = 20;
oversettes til følgende CommonJS-modul:
"use strict";
Object.defineProperty(module.exports, "__esModule", { value: true });
module.exports.x = 10;
module.exports.y = 20;
Mens navnerom har noen nyttige bruksområder, har moduler blitt den klare veien frem for å dele opp koden din i forskjellige deler.
Skriving/Typene
«Typings» var en pakkebehandler for deklarasjonsfiler (.d.ts-filer) før @types ble den foreskrevne måten å hente deklarasjonsfiler på (mer om dette snart)
Som et resultat har "typings" også blitt en slags kallenavn for deklarasjonsfiler.
Hvis du starter et nytt prosjekt, ikke bruk Typings. TypeScript-økosystemet har i stor grad standardisert bruken av npm for deklarasjonsfiler. I tillegg, på grunn av forvirringen i terminologien, bør du sannsynligvis ikke kalle deklarasjonsfiler for «typings».
Med det sagt, kan vi gå videre til følgende tema:
Deklarasjonsfiler
Deklarasjonsfiler (.d.ts-filer, også kalt definisjonsfiler) er TypeScript-filer som beskriver eksisterende kode. De kan produseres fra .ts-filer ved å bruke --declaration-flagget, eller de kan skrives manuelt for å beskrive eksisterende JavaScript-kode.
Deklarasjonsfiler inneholder deklarasjoner av koden som de faktisk beskriver. For å være mer spesifikk, den følgende TypeScript-funksjonen:
function foo(x: number, y: number) {
return x * 100 + y;
}
ville bli beskrevet av følgende erklæring:
declare function foo(x: number, y: number): number
Hvis den opprinnelige deklarasjonen ble skrevet i JavaScript, kunne den fortsatt beskrives ved hjelp av en deklarasjon med eksplisitte typer som ovenfor.
Dette er viktig fordi den store majoriteten av JavaScript-kode ikke opprinnelig er skrevet i TypeScript. Så fellesskapet har gått sammen og opprettet et arkiv med deklarasjonsfiler kalt DefinitelyTyped.
DefinitelyTyped
Dette er et stort git-repositorium som beskriver over 3000 biblioteker på tidspunktet for denne skrivingen. Brukere kan sende pull-forespørsler for rettelser og nye pakker.
Du kan ta en titt på repoet her på GitHub.
@types og npm
Slik kan du få deklarasjonsfiler fra DefinitelyTyped. For eksempel, hvis du ønsket .d.ts-filene for lodash, kunne du skrive
npm install @types/lodash
Se
- forbrukseksjonen på TypeScript-nettstedet om deklarasjonsfiler.
- kunngjøringsblogginnlegget med tittelen Fremtiden for deklarasjonsfiler
- utarbeidelsen av blogginnlegget ovenfor
Hvordan henger disse sammen?
Dessverre er ideene her subtile. Deklarasjonsfiler kan beskrive alt i TypeScript. Det betyr at de kan beskrive hvordan et modul ser ut, samt hvordan et navnerom ser ut.
Så deklarasjonsfiler tjener ikke samme formål som moduler og navnerom. Men de beskriver for TypeScript når navnerom og moduler finnes, og hvordan de kan brukes.
I utgangspunktet, hvis du noen gang trenger å bruke noe som ser ut som en modul eller et navnerom og det ble skrevet i JS, vil du trenge en deklarasjonsfil.
Selv om det ble skrevet i TypeScript, hvis det allerede var kompilert til .js, vil du da trenge en tilsvarende .d.ts-fil for å bruke det.
Jeg forstår det fortsatt ikke
Forhåpentligvis hjalp dette med å forklare, men hvis ikke, sjekk ut
- Modulseksjonen på TypeScript-nettstedet.
- TypeScript Deep Dive-seksjonen om moduler
- de ovennevnte ressursene
- Ryans merkelige godterikoppanalogi som beskriver forskjellene mellom moduler og navneområder som Cartant lenket til ovenfor.
