Jak używać przestrzeni nazw w TypeScript
Kolizja nazw występuje, gdy co najmniej dwa komponenty kodu używają tej samej nazwy dla zmiennej, funkcji lub klasy. Są powszechne w dużych projektach, w których wiele osób pracuje nad tą samą bazą kodu. Mogą utrudniać ustalenie, który składnik kodu jest odpowiedzialny za błędy.
Korzystając z przestrzeni nazw, możesz organizować swój kod i zarządzać nim, tak aby grupy powiązanych komponentów znajdowały się pod wspólnym identyfikatorem. Zmniejszy to ryzyko konfliktów nazw.
Tworzenie przestrzeni nazw
Przestrzenie nazw można tworzyć w języku TypeScript za pomocą słowa kluczowego namespace . Podążaj za nim z identyfikatorem, aby nazwać przestrzeń nazw i blok ujęty w nawiasy klamrowe. Składnia jest podobna do tej, której użyłbyś do stworzenia klasy w JavaScript.
Na przykład:
namespace Example {}
Następnie możesz zadeklarować elementy przestrzeni nazw — zmienne, funkcje i klasy — w obrębie bloku przestrzeni nazw:
namespace Example {
export function Foo(): void {
console.log("This is a function inside the Example namespace");
}
export class Bar {
property: string;
constructor(property: string) {
this.property = property;
}
}
export const baz = "This is a namespace variable"
}
W powyższym przykładzie Foo , Bar i baz są członkami przestrzeni nazw Example . Domyślnie można uzyskać dostęp tylko do członków przestrzeni nazw w tej samej przestrzeni nazw. Użyj słowa kluczowego export , aby każdy element członkowski przestrzeni nazw był dostępny poza nią.
Możesz uzyskać dostęp do wszystkich publicznie dostępnych członków przestrzeni nazw, wywołując nazwę członka przestrzeni nazw za pomocą notacji kropkowej:
Example.foo(); // This is a function inside the Example namespace
const bar = new Example.Bar("string");
console.log(bar.property); // string
console.log(Example.baz); // This is a namespace variable
Zagnieżdżanie przestrzeni nazw
TypeScript umożliwia zagnieżdżanie przestrzeni nazw w innych przestrzeniach nazw w celu stworzenia hierarchicznej struktury kodu. Zagnieżdżanie przestrzeni nazw może dodatkowo zmniejszyć ryzyko kolizji nazw poprzez grupowanie powiązanych przestrzeni nazw pod wspólnym identyfikatorem.
Na przykład:
namespace Example {
export const property_1 = "Foo";
export namespace Bar {
export const printFoo = function () {
console.log(property_1);
};
}
export namespace Baz {
export class Foo {
property: string;
constructor(property: string) {
this.property = property;
}
}
}
}
Powyższy blok kodu zawiera przykład zagnieżdżonej przestrzeni nazw. Przestrzeń nazw Example to przestrzeń nazw najwyższego poziomu, zawierająca przestrzeń nazw Bar i przestrzeń nazw Baz .
Dostęp do właściwości w zagnieżdżonej przestrzeni nazw można uzyskać za pomocą notacji kropkowej zgodnej z utworzoną strukturą hierarchiczną.
Na przykład:
console.log(Example.property_1); // Foo
Example.Bar.printFoo() // Foo
const foo = new Example.Baz.Foo("example")
Ten przykładowy kod uzyskuje dostęp do każdego elementu członkowskiego przestrzeni nazw za pośrednictwem nadrzędnej przestrzeni nazw. Bezpośredni dostęp do właściwości, zamiast przez jej nadrzędną przestrzeń nazw, spowodowałby błąd:
Example.printFoo()
// error TS2339: Property 'printFoo' does not exist on type 'typeof Example'
Chociaż zagnieżdżone przestrzenie nazw mogą pomóc w organizacji kodu, głęboko zagnieżdżone przestrzenie nazw mogą dawać odwrotny efekt. Głęboko zagnieżdżone przestrzenie nazw utrudniają czytanie i konserwację kodu.
Aliasy przestrzeni nazw
Alias przestrzeni nazw to skrócona nazwa nadana członkowi przestrzeni nazw, co ułatwia odwoływanie się do niej.
Możesz utworzyć alias przestrzeni nazw, używając słowa kluczowego import , po którym następuje nazwa, którą chcesz przypisać do aliasu. Następnie przypisz słowo kluczowe import i nazwę aliasu do elementu przestrzeni nazw.
Na przykład:
namespace Car {
export namespace Tesla {
export class ModelX {
create(): String {
return `Model X Created`
}
}
}
export namespace Toyota {
export class Camry {}
}
export namespace Ford {
export class Mustang {}
}
}
// Creating the alias
import tesla = Car.Tesla
const modelX = new tesla.ModelX()
modelX.create() // Model X Created
Ten przykład tworzy alias dla przestrzeni nazw Car.Tesla . Możesz użyć tego aliasu, aby łatwiej uzyskać dostęp do właściwości przestrzeni nazw Tesla , takich jak klasa ModelX.
Używanie przestrzeni nazw w wielu plikach
Aby użyć przestrzeni nazw w innym pliku, musisz ją zaimportować. Importowanie przestrzeni nazw różni się od importowania zmiennych, funkcji, klas itp. W zależności od systemu modułów projektu można je importować za pomocą słowa kluczowego require lub import .
Przestrzenie nazw można jednak importować tylko za pomocą dyrektywy potrójnego ukośnika, która jest jednowierszowym komentarzem zawierającym znacznik XML.
Na przykład:
// main.ts
/// <reference path="index.ts"/>
Example.foo()
W tym przykładzie zastosowano dyrektywę potrójnego ukośnika w pliku main.ts. Dyrektywa odwołuje się do pliku index.ts , który zawiera przestrzeń nazw Example . Bez importowania przestrzeń nazw jest dostępna tylko w tym samym pliku, który ją definiuje.
Po odwołaniu się do pliku index.ts można uzyskać dostęp do przestrzeni nazw Example i jej publicznie dostępnych elementów członkowskich. Na przykład możesz wywołać metodę foo w przestrzeni nazw Example .
Gdy użyjesz wielu plików, musisz upewnić się, że TypeScript skompiluje i załaduje cały niezbędny kod. Możesz to zrobić, łącząc dane wyjściowe z kompilatora TypeScript za pomocą opcji outFile . Spowoduje to skompilowanie wszystkich plików wejściowych w jeden plik wyjściowy JavaScript. Ogólna składnia uruchamiania kompilatora w następujący sposób:
tsc --outFile <JAVASCRIPT_FILE> <TYPESCRIPT_FILE>
Zastąp <JAVASCRIPT_FILE> nazwą docelowego pliku JavaScript. Zamień <TYPESCRIPT_FILE> na nazwę pliku TypeScript zawierającego dyrektywę potrójnego ukośnika.
Na przykład:
tsc --outFile index.js main.ts
To polecenie skompiluje zawartość pliku main.ts wraz ze wszystkimi plikami, do których odwołuje się dyrektywa z trzema ukośnikami, do pliku index.js .
Alternatywnie możesz określić każdy plik indywidualnie:
tsc --outFile <JAVASCRIPT_FILE> <TYPESCRIPT_FILE_1> <TYPESCRIPT_FILE_2>
Należy zauważyć, że dyrektywa potrójnego ukośnika jest ważna tylko wtedy, gdy jest zadeklarowana na początku pliku. Jeśli spróbujesz użyć go gdziekolwiek indziej, TypeScript potraktuje go jako zwykły jednowierszowy komentarz bez specjalnego znaczenia.
Czy powinieneś używać przestrzeni nazw lub modułów?
Chociaż przestrzenie nazw nie są przestarzałe, często zaleca się organizowanie kodu i zarządzanie nim za pomocą modułów ES6. Moduły są łatwiejsze w utrzymaniu i zarządzaniu, a ich zasięg można rozszerzyć na wiele plików.
Dodatkowo można określić relacje między modułami w zakresie importów i eksportów na poziomie pliku. Przestrzenie nazw nie mogą definiować swoich zależności.
Ostatecznie wybór między przestrzeniami nazw i modułami będzie zależał od konkretnych potrzeb i wymagań twojego projektu, ponieważ oba oferują cenny sposób organizowania kodu i zarządzania nim w TypeScript.
Dodaj komentarz