Ein Blog

Bei TypeScript wurde neulich der Pull-Request Control Flow Analysis for Destructured Discriminated Unions gemergt. Das hört sich erstmal kompliziert an, das Prinzip ist aber ganz simpel: Wenn eine Variable aus einem Objekt kommt, und mit der Variable irgendwelche Überprüfungen stattfinden, hat das auch Auswirkungen auf den Typen des Objekts, aus dem die Variable ursprünglich mal kam.

Bisher konnte man den Kontrollfluss auch schon verwenden, um den Typen des Objekts genauer zu spezifizieren. Allerdings musste man dann immer direkt auf das Objekt referenzieren:

type Action =
    | { kind: 'A', payload: number }
    | { kind: 'B', payload: string };

function f11(action: Action) {
    if (action.kind === 'A') {
        // `action.kind` ist 'A', daher ist `action.payload` an dieser Stelle eine number
        action.payload.toFixed();
    }
    if (action.kind === 'B') {
        // `action.kind` ist 'B', daher ist `action.payload` an dieser Stelle ein string
        action.payload.toUpperCase();
    }
}

Das neue aus dem PR ist, dass das Destructuring die Verbindung zur Herkunft nicht verliert. Und das funktioniert jetzt sogar bi-direktional. Also funktioniert jetzt auch das:

type Action =
    | { kind: 'A', payload: number }
    | { kind: 'B', payload: string };

function f11(action: Action) {
    const { kind, payload } = action;
    if (kind === 'A') {
        // `kind` kam aus `action`, daher ist `payload` an dieser Stelle eine number
        payload.toFixed();
    }
    if (kind === 'B') {
        // `kind` kam aus `action`, daher ist `payload` an dieser Stelle ein string
        payload.toUpperCase();
    }
}

Ich will mir garnicht ausmalen, wie komplex die Umsetzung dafür gewesen sein muss.