Wir haben die Hauptmerkmale des TypeScript Type Systems bereits in der Diskussion „Warum TypeScript?“ behandelt. Nachfolgend ein paar wichtige Erkenntnisse aus dieser Diskussion, die keiner weiteren Erklärung bedürfen:

  • Das Type System in TypeScript ist so konzipiert, dass es optional ist, damit Ihr JavaScript TypeScript ist.

  • TypeScript blockiert die Ausgabe von JavaScript bei Vorhandensein von Type-Fehlern nicht, so dass Sie Ihr JS schrittweise auf TS aktualisieren können.

Lassen Sie uns nun mit der Syntax des TypeScript-Typsystems beginnen. Auf diese Weise können Sie diese Annotationen sofort in Ihrem Code verwenden und den Nutzen erkennen. Dies wird Sie auf einen späteren tieferen Einstieg vorbereiten.

Wie bereits erwähnt, werden Typen mit der :TypeAnnotation-Syntax annotiert. Alles, was im Typendeklarationsraum verfügbar ist, kann als Type Annotation verwendet werden.

Das folgende Beispiel zeigt Type Annotations für Variablen, Funktionsparameter und Funktionsrückgabewerte:

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

Primitive Typen

Die primitiven Typen von JavaScript sind im TypeScript-Typsystem gut vertreten. Dies bedeutet string, number, boolean wie unten gezeigt:

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

Arrays

TypeScript bietet eine spezielle Typsyntax für Arrays, um Ihnen die Kommentierung und Dokumentation Ihres Codes zu erleichtern. Die Syntax besteht im Wesentlichen darin, an jede gültige Typ-Annotation anzuhängen (z. B. :boolean). Damit können Sie alle Array-Manipulationen, die Sie normalerweise vornehmen würden, sicher durchführen und sind vor Fehlern wie der Zuweisung eines Elements des falschen Typs geschützt. Dies wird im Folgenden veranschaulicht:

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

Schnittstellen

Schnittstellen sind die zentrale Methode in TypeScript, um mehrere Typ-Annotationen in einer einzigen benannten Annotation zusammenzufassen. Betrachten Sie das folgende Beispiel:

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
};

Hier haben wir die Annotationen first: string + second: string zu einer neuen Annotation Name zusammengefasst, die die Typüberprüfungen für einzelne Mitglieder durchsetzt. Schnittstellen sind in TypeScript sehr mächtig, und wir werden einen ganzen Abschnitt dem widmen, wie man das zu seinem Vorteil nutzen kann.

Inline-Type-Annotation

Anstatt eine neue interface zu erstellen, kann man mit :{ /*Structure*/ } alles, was man will, inline annotieren. Das vorangegangene Beispiel zeigt wieder einen Inline-Typ:

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-Typen eignen sich hervorragend, um schnell eine einmalige Typbezeichnung für etwas zu erstellen. Sie ersparen Ihnen die Mühe, sich einen (möglicherweise schlechten) Typnamen auszudenken. Wenn Sie jedoch feststellen, dass Sie dieselbe Typ-Annotation mehrmals inline eingeben, ist es eine gute Idee, sie in eine Schnittstelle umzuwandeln (oder in eine type alias, die später in diesem Abschnitt behandelt wird).

Spezielle Typen

Neben den primitiven Typen, die behandelt wurden, gibt es einige Typen, die in TypeScript eine besondere Bedeutung haben. Diese sind any, null, undefined, void.

alle

Der Typ any nimmt einen besonderen Platz im TypeScript-Typsystem ein. Er gibt Ihnen eine Fluchtmöglichkeit aus dem Typsystem, um dem Compiler zu sagen, dass er sich verpissen soll. any ist mit allen Typen des Typsystems kompatibel. Das bedeutet, dass ihm alles zugewiesen werden kann und er kann allem zugewiesen werden. Dies wird im folgenden Beispiel demonstriert:

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

Wenn Sie JavaScript-Code nach TypeScript portieren, werden Sie anfangs eng mit any befreundet sein. Nehmen Sie diese Freundschaft jedoch nicht zu ernst, denn sie bedeutet, dass es an Ihnen liegt, die Typsicherheit zu gewährleisten. Sie sagen dem Compiler im Grunde, dass er keine sinnvolle statische Analyse durchführen soll.

null und undefiniert

Wie sie vom Typsystem behandelt werden, hängt vom strictNullChecks Compiler-Flag ab (wir behandeln dieses Flag später). Wenn sie in strictNullCheck:false stehen, werden die null– und undefined-JavaScript-Literale vom Typsystem genauso behandelt wie etwas vom Typ any. Diese Literale können jedem anderen Typ zugewiesen werden. Dies wird im folgenden Beispiel demonstriert:

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

:void

Verwenden Sie :void, um anzuzeigen, dass eine Funktion keinen Rückgabetyp hat:

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

Generics

Viele Algorithmen und Datenstrukturen in der Informatik hängen nicht vom tatsächlichen Typ des Objekts ab. Dennoch möchte man eine Einschränkung zwischen verschiedenen Variablen erzwingen. Ein einfaches Beispiel ist eine Funktion, die eine Liste von Elementen annimmt und eine umgekehrte Liste von Elementen zurückgibt. Die Einschränkung besteht hier zwischen dem, was an die Funktion übergeben wird, und dem, was von der Funktion zurückgegeben wird:

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

Hier sagen Sie im Grunde, dass die Funktion reverse ein Array (items: T) vom Typ T (beachten Sie den Typ-Parameter in reverse<T>) annimmt und ein Array vom Typ T (beachten Sie : T) zurückgibt. Da die Funktion reverse Elemente desselben Typs zurückgibt, weiß TypeScript, dass die Variable reversed ebenfalls vom Typ number ist und gibt Ihnen Typsicherheit. Wenn Sie der umgekehrten Funktion ein Array vom Typ string übergeben, ist das zurückgegebene Ergebnis ebenfalls ein Array vom Typ string, und Sie erhalten eine ähnliche Typsicherheit wie unten gezeigt:

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

JavaScript-Arrays haben bereits eine Funktion .reverse, und TypeScript verwendet in der Tat Generics, um ihre Struktur zu definieren:

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

Das bedeutet, dass man Typsicherheit erhält, wenn man .reverse auf einem beliebigen Array aufruft, wie unten gezeigt:

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

Wir werden später mehr über die Schnittstelle Array<T> diskutieren, wenn wir lib.d.ts im Abschnitt Ambient Declarations vorstellen.

Union Type

Häufig möchte man in JavaScript, dass eine Eigenschaft eine von mehreren Typen ist, z.B. eine string oder eine number. Hier kommt der Union-Typ (bezeichnet durch | in einer Typ-Annotation, z. B. string|number) ins Spiel. Ein häufiger Anwendungsfall ist eine Funktion, die ein einzelnes Objekt oder ein Array des Objekts aufnehmen kann, z. B.:

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

Intersection Type

extend ist ein sehr verbreitetes Muster in JavaScript, bei dem man zwei Objekte nimmt und ein neues erstellt, das die Eigenschaften dieser beiden Objekte hat. Ein Intersection Type erlaubt es Ihnen, dieses Muster auf sichere Weise zu verwenden, wie im Folgenden gezeigt wird:

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 unterstützt keine Tupel erster Klasse. In der Regel wird einfach ein Array als Tupel verwendet. Genau das unterstützt das TypeScript-Typsystem. Tupel können mit : usw. annotiert werden. Ein Tupel kann eine beliebige Anzahl von Mitgliedern haben. Tupel werden im folgenden Beispiel demonstriert:

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

Kombiniert man dies mit der Destrukturierungsunterstützung in TypeScript, fühlen sich Tupel ziemlich erstklassig an, obwohl sie darunter Arrays sind:

var nameNumber: ;
nameNumber = ;
var = nameNumber;

Type Alias

TypeScript bietet eine bequeme Syntax für die Bereitstellung von Namen für Typ-Annotationen, die Sie an mehr als einer Stelle verwenden möchten. Die Aliasnamen werden mit der type SomeName = someValidTypeAnnotation-Syntax erstellt. Ein Beispiel wird im Folgenden gezeigt:

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

Im Gegensatz zu interface können Sie einen Typ-Alias für buchstäblich jede Typ-Anmerkung vergeben (nützlich für Dinge wie Union- und Schnittpunkt-Typen). Hier sind ein paar weitere Beispiele, um Sie mit der Syntax vertraut zu machen:

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

TIP: Wenn Sie Hierarchien von Typ-Anmerkungen benötigen, verwenden Sie eine interface. Sie können mit implements und extends

verwendet werden

TIP: Verwenden Sie einen Typ-Alias für einfachere Objektstrukturen (wie Coordinates), um ihnen einen semantischen Namen zu geben. Auch wenn Sie Union- oder Intersection-Typen semantische Namen geben wollen, ist ein Type-Alias der richtige Weg.

Zusammenfassung

Nun, da Sie die meisten Ihrer JavaScript-Codes annotieren können, können wir uns in die Details all der Möglichkeiten stürzen, die in TypeScripts Type System verfügbar sind.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.