Großteil der React-Projekte verwendet TypeScript anstatt von JavaScript
Statische Typisierung → bessere Autovervollständigung und Fehlererkennung
Themen:
Datentypen können explizit vom Entwickler angegeben werden oder von der Entwicklungsumgebung abgeleitet werden (engl. type inference)
Vortile:
Beispiel:
let names: Array<string> = [];
names.push('Alice');
names.push('Bob');
console.log(names[0].toUpperCase());
online mit TypeScript experimentieren:
Datentypen, die wir verwenden werden:
Variablentypen können beim Deklarieren von Variablen angegeben werden:
let age: number = 32;
in vielen Fällen kennt TypeScript den Typ automatisch (keine Annotation notwendig):
let age = 32;
const age: number = 32;
const name: string = 'Alice';
const loggedIn: boolean = true;
const names: Array<string> = [];
names.push('Alice');
alternative Schreibweise:
const names: string[] = [];
names.push('Alice');
Typendeklaration:
let todo: {
id: number;
title: string;
completed: boolean;
};
Zuweisung:
todo = { id: 1, title: 'foo', completed: false };
optionale Einträge werden mit ?
gekennzeichnet
let todo: {
id: number;
title: string;
completed: boolean;
date?: string;
};
Kombination der Deklarationen:
let todos: Array<{
id: number;
title: string;
completed: boolean;
}>;
todos = [
{ id: 1, title: 'foo', completed: false },
{ id: 2, title: 'bar', completed: true },
];
Manchmals möchten wir die Typenüberprüfung aufheben:
const nameInput: any = document.getElementById(
'name-input'
);
console.log(nameInput.value);
Deklarieren wir eine Variable als any
, können wir auf beliebige Properties zugreifen
Variablen, die mehrere Typen annehmen können:
let width: string | number | undefined;
width = '16px';
width = 16;
Type Aliases oder Interfaces: Möglichkeiten, eine Typendeklaration unter einem Namen zu speichern
werden vor Allem für Objektstrukturen verwendet, z.B.:
type Todo = {
id: number;
title: string;
completed: boolean;
};
Type Alias für ein Objekt:
type Todo = {
id: number;
title: string;
completed: boolean;
};
Interface für ein Objekt:
interface Todo {
id: number;
title: string;
completed: boolean;
}
Type Aliases können etwas einfacher und flexibler sein als Interfaces (Vergleich auf StackOverflow)
const todos: Array<Todo> = [
{ id: 1, title: 'foo', completed: false },
{ id: 2, title: 'bar', completed: true },
];
Type Aliases und Interfaces sollten groß geschrieben werden (z.B. Todo
, nicht todo
)
function shorten(text: string, maxLen: number): string {
// ...
}
const shorten = (text: string, maxLen: number): string => {
// ...
};
Funktionen ohne Rückgabewert: void
function logMessage(message: string): void {
console.log(message);
}
Beispiel: Event-Handler in React:
import { MouseEvent } from 'react';
function handleClick(event: MouseEvent): void {
event.stopPropagation();
// ...
}
<button onClick={handleClick}>click</button>
wichtige Eventtypen in React:
React.FormEvent
(z.B. Submit)React.ChangeEvent
React.MouseEvent
(z.B. Click)Speichern einer Funktionssignatur unter einem Type Alias:
// a validator is a function that receives a string
// and returns a boolean
type Validator = (s: string) => boolean;
Anwenden der Type Alias:
const validateEmail: Validator = (s) => s.includes('@');
const validateYear: Validator = (s) =>
new RegExp('^d{4}$').test(s);
beim schreiben von eigenen React-Komponenten werden wir Eventhandler-Funktionen als Props übergeben:
type TodoListProps = {
// properties
todos: Array<Todo>;
// event handlers
onDelete: (id: number) => void;
onChangeCompleted: (id: number, completed: boolean) => void;
}
Generic: allgemeine Typendeklaration, zu der bei der Anwendung nähere Informationen spezifiziert werden können (via <...>
)
Beispiel: Array
ist ein Generic
const names: Array<string> = ['Alice', 'Bob', 'Charlie'];
Beispiel: Reacts useState
kann als Generic verwendet werden
const [todos, setTodos] = useState<Array<Todo>>([]);
Beispiel: Reacts Eventtypen können als Generics verwendet werden:
function handleChange(
event: ChangeEvent<HTMLInputElement>
) {
const newValue = event.target.value;
// ...
}
Type Assertions ermöglichen das Behandeln eines vorhandenen Objekts als bestimmter Typ
dies schlägt fehl:
// type: HTMLElement or null
const nameInput = document.getElementById('name-input');
console.log(nameInput.value);
dies klappt:
const nameInput = document.getElementById(
'name-input'
) as HTMLInputElement;
console.log(nameInput.value);
Type Assertions können auch mit any
arbeiten:
const nameInput = document.getElementById(
'name-input'
) as any;
console.log(nameInput.value);
Browser verstehen nur JavaScript, nicht TypeScript
Beim build: TypeScript wird in JavaScript übersetzt, alle Typeninformationen gehen dabei verloren
Manche JavaScript Libraries beinhalten TypeScript-Deklarationen - z.B. redux.
Andere verbreitete Libraries haben meist Typendeklarations-Pakete mit dem Präfix @types
z.B. für react: @types/react
React+TypeScript Cheatsheets: https://github.com/typescript-cheatsheets/react