Discriminated Unions
Discriminated Union
Якщо у вас є клас ізliteral member, ви можете використовувати цю властивість для розрізнення членів об’єднання.
Як приклад розглянемо об’єднання Square і Rectangle, тут ми маємо член kind який існує в обох членах об’єднання та має певний literal type:
interface Square {
kind: "square";
size: number;
}
interface Rectangle {
kind: "rectangle";
width: number;
height: number;
}
type Shape = Square | Rectangle;Якщо ви використовуєте перевірку стилю захисту типу (==, ===, !=, !==) або switch на discriminant property (тут kind) TypeScript зрозуміє що об’єкт має бути типу, який має цей конкретний літерал, і додасть тип за вас :)
function area(s: Shape) {
if (s.kind === "square") {
// Зараз TypeScript *знає* що `s` має бути square ;)
// Тож ви можете безпечно використовувати його учасників :)
return s.size * s.size;
}
else {
// Це не square? TypeScript зрозуміє, що це має бути Rectangle ;)
// Тож ви можете безпечно використовувати його учасників :)
return s.width * s.height;
}
}Exhaustive Checks
Вичерпні перевірки.
Досить часто ви хочете переконатися, що всі члени мають певний код
Як приклад того, де все йде погано:
Ви можете зробити це, просто додавши пропуск і переконавшись, що виведений тип у цьому блоці сумісний із типом never. Наприклад, якщо ви додасте вичерпну перевірку, ви отримаєте гарну помилку:
Це змушує вас розглядати цю нову справу:
Switch
ПОРАДА: звичайно, ви також можете зробити це в операторі switch:
strictNullChecks
Якщо використовується strictNullChecks і виконуються вичерпні перевірки, TypeScript може скаржитися, що «не всі шляхи коду повертають значення». Ви можете заглушити це, просто повернувши змінну _exhaustiveCheck (типу never). Так:
Throw in exhaustive checks
Ви можете написати функцію, яка приймає never (і тому може бути викликана лише зі змінною, яка виводиться як never), а потім видає помилку, якщо її тіло коли-небудь виконується:
Приклад використання функції площі:
Retrospective Versioning
Скажімо, у вас є структура даних у формі:
І після того, як у вас є купа DTO, ви розумієте, що name було поганим вибором. Ви можете додати керування версіями ретроспективно, створивши новий union з literal number (або рядком, якщо хочете) DTO. Позначте версію 0 як undefined якщо у вас увімкнено strictNullChecks, це просто спрацює:
Приклад використання такого DTO:
Redux
Популярною бібліотекою, яка використовує це, є redux.
Ось gist of reduxіз доданими анотаціями типу TypeScript:
Використання його з TypeScript забезпечує захист від друкарських помилок, покращує здатність до рефакторингу та самодокументування коду.
Last updated