TypeScript für React

TypeScript für React

Großteil der React-Projekte verwendet TypeScript anstatt von JavaScript

Statische Typisierung → bessere Autovervollständigung und Fehlererkennung

TypeScript für React

Themen:

  • grundlegende Typendeklarationen
  • Type Aliases und Interfaces
  • Parametertypen und Rückgabetypen von Funktionen
  • Generics
  • Type Assertions

Statische Typisierung

Datentypen können explizit vom Entwickler angegeben werden oder von der Entwicklungsumgebung abgeleitet werden (engl. type inference)

Vortile:

  • bessere Autovervollständigung
  • bessere Fehlererkennung

Statische Typisierung

Beispiel:

let names: Array<string> = [];

names.push('Alice');
names.push('Bob');

console.log(names[0].toUpperCase());

Playground

online mit TypeScript experimentieren:

https://www.typescriptlang.org/play

Datentypen und Typendeklarationen

Datentypen und Typendeklarationen

Datentypen, die wir verwenden werden:

  • boolean
  • number
  • string
  • array
  • object

Variablentypen

Variablentypen können beim Deklarieren von Variablen angegeben werden:

let age: number = 32;

Type Inference

in vielen Fällen kennt TypeScript den Typ automatisch (keine Annotation notwendig):

let age = 32;

Primitive Typen

const age: number = 32;
const name: string = 'Alice';
const loggedIn: boolean = true;

Array-Typen

const names: Array<string> = [];
names.push('Alice');

alternative Schreibweise:

const names: string[] = [];
names.push('Alice');

Objekttypen

Typendeklaration:

let todo: {
  id: number;
  title: string;
  completed: boolean;
};

Zuweisung:

todo = { id: 1, title: 'foo', completed: false };

Objekttypen

optionale Einträge werden mit ? gekennzeichnet

let todo: {
  id: number;
  title: string;
  completed: boolean;
  date?: string;
};

Kombination

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

Any

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

Union Types

Variablen, die mehrere Typen annehmen können:

let width: string | number | undefined;

width = '16px';
width = 16;

Type Aliases und Interfaces

Type Aliases und Interfaces

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 Aliases und Interfaces

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 und Interfaces

Type Aliases können etwas einfacher und flexibler sein als Interfaces (Vergleich auf StackOverflow)

Verwendung von Type Aliases / Interfaces

const todos: Array<Todo> = [
  { id: 1, title: 'foo', completed: false },
  { id: 2, title: 'bar', completed: true },
];

Type Aliases und Interfaces

Type Aliases und Interfaces sollten groß geschrieben werden (z.B. Todo, nicht todo)

Funktionssignaturen und Funktionstypen

Funktionssignaturen

function shorten(text: string, maxLen: number): string {
  // ...
}
const shorten = (text: string, maxLen: number): string => {
  // ...
};

Funktionssignaturen

Funktionen ohne Rückgabewert: void

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

Event-Handler in React

Beispiel: Event-Handler in React:

import { MouseEvent } from 'react';
function handleClick(event: MouseEvent): void {
  event.stopPropagation();
  // ...
}
<button onClick={handleClick}>click</button>

Event-Handler in React

wichtige Eventtypen in React:

  • React.FormEvent (z.B. Submit)
  • React.ChangeEvent
  • React.MouseEvent (z.B. Click)

Funktionstypen

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

Funktionstypen

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

Generics

Generics

Generic: allgemeine Typendeklaration, zu der bei der Anwendung nähere Informationen spezifiziert werden können (via <...>)

Generics

Beispiel: Array ist ein Generic

const names: Array<string> = ['Alice', 'Bob', 'Charlie'];

Generics

Beispiel: Reacts useState kann als Generic verwendet werden

const [todos, setTodos] = useState<Array<Todo>>([]);

Generics

Beispiel: Reacts Eventtypen können als Generics verwendet werden:

function handleChange(
  event: ChangeEvent<HTMLInputElement>
) {
  const newValue = event.target.value;
  // ...
}

Type Assertions

Type Assertions

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

Type Assertions können auch mit any arbeiten:

const nameInput = document.getElementById(
  'name-input'
) as any;
console.log(nameInput.value);

TypeScript: diverses

Build

Browser verstehen nur JavaScript, nicht TypeScript

Beim build: TypeScript wird in JavaScript übersetzt, alle Typeninformationen gehen dabei verloren

Typendeklarationen für Libraries

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

Cheatsheets

React+TypeScript Cheatsheets: https://github.com/typescript-cheatsheets/react