Hlavními vlastnostmi TypeScriptu jsme se zabývali již v kapitole Proč TypeScript?. Následuje několik klíčových poznatků z této diskuse, které není třeba dále vysvětlovat:

  • Typový systém v jazyce TypeScript je navržen jako volitelný, takže váš JavaScript je TypeScript.

  • TypeScript neblokuje vysílání JavaScriptu v přítomnosti typových chyb, což vám umožňuje postupně aktualizovat váš JS na TS.

Nyní začněme se syntaxí typového systému TypeScript. Takto můžete tyto anotace začít ihned používat ve svém kódu a uvidíte jejich přínos. Připravíte se tak na pozdější hlubší ponor.

Jak již bylo řečeno, typy se anotují pomocí syntaxe :TypeAnnotation. Cokoli, co je k dispozici v prostoru deklarace typu, lze použít jako anotaci typu.

Následující příklad demonstruje anotace typu pro proměnné, parametry funkcí a návratové hodnoty funkcí:

var num: number = 123;
function identity(num: number): number {
return num;
}

Primitivní typy

Primitivní typy jazyka JavaScript jsou v typovém systému TypeScript dobře zastoupeny. To znamená string, number, boolean, jak je ukázáno níže:

var num: number;
var str: string;
var bool: boolean;
num = 123;
num = 123.456;
num = '123'; // Error
str = '123';
str = 123; // Error
bool = true;
bool = false;
bool = 'false'; // Error

Pole

TypeScript poskytuje speciální typovou syntaxi pro pole, aby vám usnadnil anotaci a dokumentaci kódu. Syntaxe spočívá v podstatě v postfixování k libovolné platné typové anotaci (např. :boolean). Umožňuje vám bezpečně provádět jakoukoli manipulaci s polem, kterou byste normálně prováděli, a chrání vás před chybami, jako je přiřazení členu nesprávného typu. To je demonstrováno níže:

var boolArray: boolean;
boolArray = ;
console.log(boolArray); // true
console.log(boolArray.length); // 2
boolArray = true;
boolArray = ;
boolArray = 'false'; // Error!
boolArray = 'false'; // Error!
boolArray = ; // Error!

Rozhraní

Rozhraní jsou základním způsobem, jak v jazyce TypeScript složit více typových anotací do jedné pojmenované anotace. Uvažujme následující příklad:

interface Name {
first: string;
second: string;
}
var name: Name;
name = {
first: 'John',
second: 'Doe'
};
name = { // Error : `second` is missing
first: 'John'
};
name = { // Error : `second` is the wrong type
first: 'John',
second: 1337
};

Zde jsme složili anotace first: string + second: string do nové anotace Name, která vynucuje typové kontroly jednotlivých členů. Rozhraní mají v TypeScriptu velkou sílu a my věnujeme celou sekci tomu, jak ji můžete využít ve svůj prospěch.

Inline typová anotace

Místo vytváření nové interface můžete pomocí :{ /*Structure*/ } anotovat inline cokoli chcete. Předchozí příklad prezentovaný opět s inline typem:

var name: {
first: string;
second: string;
};
name = {
first: 'John',
second: 'Doe'
};
name = { // Error : `second` is missing
first: 'John'
};
name = { // Error : `second` is the wrong type
first: 'John',
second: 1337
};

Inline typy jsou skvělé pro rychlé poskytnutí jednorázové anotace typu pro něco. Ušetří vám práci s vymýšlením (potenciálně špatného) názvu typu. Pokud však zjistíte, že vkládáte stejnou anotaci typu inline vícekrát, je dobré zvážit její refaktorizaci do rozhraní (nebo type alias, kterému se budeme věnovat později v této části).

Speciální typy

Kromě primitivních typů, kterým jsme se věnovali, existuje několik typů, které mají v jazyce TypeScript zvláštní význam. Jsou to typy any, null, undefined, void.

libovolný

Typ any má v typovém systému jazyka TypeScript zvláštní místo. Poskytuje vám únikový východ z typového systému, kterým můžete kompilátoru říct, ať si trhne nohou. Typ any je kompatibilní se všemi typy v typovém systému. To znamená, že mu lze přiřadit cokoli a může být přiřazen čemukoli. To je demonstrováno na následujícím příkladu:

var power: any;
// Takes any and all types
power = '123';
power = 123;
// Is compatible with all types
var num: number;
power = num;
num = power;

Pokud přenášíte kód JavaScriptu do jazyka TypeScript, budete se zpočátku s typem any velmi přátelit. Toto přátelství však neberte příliš vážně, protože to znamená, že je na vás, abyste zajistili typovou bezpečnost. V podstatě tím kompilátoru říkáte, aby neprováděl žádnou smysluplnou statickou analýzu.

null a undefined

Jak s nimi bude typový systém zacházet, závisí na příznaku kompilátoru strictNullChecks (tomuto příznaku se budeme věnovat později). Jsou-li v strictNullCheck:false, zachází typový systém s null a undefined JavaScriptovými literály efektivně stejně jako s něčím typu any. Tyto literály lze přiřadit jakémukoli jinému typu. To je demonstrováno na následujícím příkladu:

var num: number;
var str: string;
// These literals can be assigned to anything
num = null;
str = undefined;

:void

Pro označení, že funkce nemá návratový typ, použijte :void:

function log(message): void {
console.log(message);
}

Generics

Mnoho algoritmů a datových struktur v informatice nezávisí na skutečném typu objektu. Přesto však chcete vynutit omezení mezi různými proměnnými. Jednoduchým příkladem na hraní je funkce, která přijímá seznam položek a vrací obrácený seznam položek. Omezení je zde mezi tím, co je předáno funkci, a tím, co funkce vrací:

function reverse<T>(items: T): T {
var toreturn = ;
for (let i = items.length - 1; i >= 0; i--) {
toreturn.push(items);
}
return toreturn;
}
var sample = ;
var reversed = reverse(sample);
console.log(reversed); // 3,2,1
// Safety!
reversed = '1'; // Error!
reversed = ; // Error!
reversed = 1; // Okay
reversed = ; // Okay

Tady v podstatě říkáte, že funkce reverse přijímá pole (items: T) nějakého typu T (všimněte si typového parametru v reverse<T>) a vrací pole typu T (všimněte si : T). Protože funkce reverse vrací položky stejného typu jako přijímá, TypeScript ví, že proměnná reversed je také typu number, a poskytne vám typovou bezpečnost. Podobně pokud funkci reverse předáte pole string, vrácený výsledek je také pole string a získáte podobnou typovou bezpečnost, jak je uvedeno níže:

var strArr = ;
var reversedStrs = reverse(strArr);
reversedStrs = ; // Error!

Ve skutečnosti mají pole JavaScriptu již funkci .reverse a TypeScript skutečně používá generika k definování jeho struktury:

interface Array<T> {
reverse(): T;
// ...
}

To znamená, že při volání funkce .reverse na libovolné pole získáte typovou bezpečnost, jak ukazuje následující obrázek:

var numArr = ;
var reversedNums = numArr.reverse();
reversedNums = ; // Error!

O rozhraní Array<T> si povíme více později, až si představíme lib.d.ts v části Deklarace prostředí.

Typ unie

Zcela běžně v JavaScriptu chcete umožnit, aby vlastnost byla jedním z více typů, například string nebo number. Zde se hodí typ union (označený | v anotaci typu, např. string|number). Běžným případem použití je funkce, která může přijmout jeden objekt nebo pole objektů, např:

function formatCommandline(command: string|string) {
var line = '';
if (typeof command === 'string') {
line = command.trim();
} else {
line = command.join(' ').trim();
}
// Do stuff with line: string
}

Typ Intersection

extend je v JavaScriptu velmi častý vzor, kdy vezmete dva objekty a vytvoříte nový, který má vlastnosti obou těchto objektů. Intersekční typ umožňuje použít tento vzor bezpečným způsobem, jak je ukázáno níže:

function extend<T, U>(first: T, second: U): T & U {
return { ...first, ...second };
}
const x = extend({ a: "hello" }, { b: 42 });
// x now has both `a` and `b`
const a = x.a;
const b = x.b;

Tuple Type

JavaScript nemá podporu tuple první třídy. Lidé obvykle používají jako tuple pouze pole. Přesně to podporuje typový systém jazyka TypeScript. Tuply lze anotovat pomocí : atd. Tuple může mít libovolný počet členů. Tuply jsou demonstrovány na následujícím příkladu:

var nameNumber: ;
// Okay
nameNumber = ;
// Error!
nameNumber = ;

Kombinujeme-li to s podporou destrukce v jazyce TypeScript, působí tuply poměrně prvotřídně, přestože se pod nimi skrývají pole:

var nameNumber: ;
nameNumber = ;
var = nameNumber;

Type Alias

TypeScript poskytuje pohodlnou syntaxi pro poskytování názvů pro anotace typů, které chcete použít na více než jednom místě. Aliasy se vytvářejí pomocí syntaxe type SomeName = someValidTypeAnnotation. Příklad je demonstrován níže:

type StrOrNum = string|number;
// Usage: just like any other notation
var sample: StrOrNum;
sample = 123;
sample = '123';
// Just checking
sample = true; // Error!

Na rozdíl od interface můžete dát typový alias doslova jakékoli typové anotaci (užitečné pro věci, jako jsou typy union a intersection). Zde je několik dalších příkladů, abyste se seznámili se syntaxí:

type Text = string | { text: string };
type Coordinates = ;
type Callback = (data: string) => void;

TIP: Pokud potřebujete mít hierarchii typových anotací, použijte interface. Lze je použít s implements a extends

TIP: Pro jednodušší objektové struktury (jako Coordinates) použijte typový alias, jen abyste jim dali sémantické jméno. Také když chcete dát sémantické názvy typům Union nebo Intersection, je alias typu tou správnou cestou.

Shrnutí

Teď, když můžete začít anotovat většinu svého kódu v jazyce JavaScript, můžeme se vrhnout na detailní informace o všech možnostech, které jsou k dispozici v systému typů TypeScript.

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna.