Przejdź do treści
webtype.orgDwanaście zagadnień · 5/12

Zagadnienie 5 z 12

Modyfikatory

Modyfikatory to drobny druk typów mapowanych. Łatwo je napisać i łatwo subtelnie pomylić, bo domyślne zachowanie — ciche kopiowanie tego, co już było — wygląda identycznie jak nierobienie niczego.

Mapowania homomorficzne dziedziczą modyfikatory

interface Draft { title?: string; readonly id: number }

// Mapping over bare `keyof T` preserves ? and readonly:
type Copy<T> = { [K in keyof T]: T[K] }
type Same = Copy<Draft>   // { title?: string; readonly id: number }

// Mapping over a computed key set does NOT:
type Flat<T> = { [K in keyof T | never]: T[K] }
type Bare = Flat<Draft>   // { title: string; id: number }

Mapowanie jest homomorficzne tylko wtedy, gdy zbiór kluczy to dokładnie `keyof T` dla parametru `T`. Wylicz zbiór inaczej — złącz, przefiltruj, przemianuj przez `as` — a wszystkie modyfikatory domyślnie przepadną.

To zaskakuje przy pisaniu typu `Merge`: wynik traci opcjonalność z obu źródeł i nic o tym nie ostrzega.

`-?` usuwa też undefined

type T = { a?: string }        // a?: string | undefined
type R = { [K in keyof T]-?: T[K] }
// { a: string }  — not { a: string | undefined }

Odjęcie modyfikatora opcjonalności robi dwie rzeczy naraz: klucz staje się wymagany, a z typu wartości znika `undefined`. Tę drugą łatwo przeoczyć — i zwykle właśnie o nią chodziło.

Najczęstsza błędna odpowiedź

// Intent: make everything optional.
type Loose<T> = { [K in keyof T]: T[K] | undefined }

// The key is still required — you must write { a: undefined }
// rather than omitting it. Optional and "may be undefined"
// are genuinely different properties.

Rozszerzenie wartości to nie to samo co uczynienie klucza opcjonalnym, a testy dokładnej równości je rozróżniają. Jeśli chodziło o opcjonalność, `?` należy postawić po klauzuli klucza.

Do zapamiętania

Modyfikatory działają na właściwości, nigdy na wartości. A mapowanie, które w ogóle rusza zbiór kluczy, zapomina każdy modyfikator, którego nie kazano mu zachować.

Ćwiczone w