Nominal Typing
Nominal Typing
Система типів TypeScript є структурною і це одна з головних мотиваційних переваг. Однак існують випадки реального використання системи, де потрібно, щоб дві змінні були розрізнені, оскільки вони мають різні назви типу, навіть якщо вони мають однакову структуру. Дуже поширеним випадком використання є структури ідентичності (які, як правило, являють собою просто рядки з семантикою, пов’язаною з їх ім’ям у таких мовах, як C#/Java).
Є кілька моделей, які виникли в спільноті. Я розглядаю їх у порядку зменшення особистих переваг:
Using literal types
У цьому шаблоні використовуються узагальнені та літеральні типи:
Переваги
Немає потреби в твердженнях будь-якого типу
Недолік
Структура
{type,value}
може бути небажаною та потребувати підтримки серверної серіалізації
Using Enums
Enums у TypeScript пропонують певний рівень номінальної типізації. Два типи перерахувань не є рівноправними, якщо вони відрізняються за назвою. Ми можемо використовувати цей факт для забезпечення номінальної типізації для типів, які в іншому структурно сумісні.
Обхідний шлях передбачає:
Створення переліку brand.
Створення типу як перетину (
&
) переліку бренду + фактичної структури.
Це показано нижче, де структура типів є лише рядком:
Зверніть увагу, що переліки брендів FooIdBrand і BarIdBrand вище мають один елемент (_), який відповідає порожньому рядку, як зазначено в _ = ""
. Це змушує TypeScript зробити висновок, що це переліки на основі рядків зі значеннями типу string
, а не переліки зі значеннями типу number
. Це необхідно, оскільки TypeScript робить висновок, що порожнє перелічення ({}
) є числовим переліком, а з TypeScript 3.6.2 перетин числового enum
і string
є never
.
Using Interfaces
Оскільки numbers
є типом сумісним з enum
, попередня техніка не може бути використана для них. Замість цього ми можемо використовувати інтерфейси, щоб порушити структурну сумісність. Цей метод досі використовується командою компіляторів TypeScript, тому варто згадати. Використання префікса _
і суфікса Brand
є угодою, яку я настійно рекомендую (і [той, якої дотримується команда TypeScript](https://github.com/Microsoft/TypeScript/blob/7b48a182c05ea4dea81bab73ecbbe9e013a79e99/src/compiler/types .ts#L693-L698)).
Обхідний шлях передбачає наступне:
додавання невикористаної властивості до типу для порушення структурної сумісності.
використання твердження типу, коли потрібно оновити або ліквідувати.
Це показано нижче:
Last updated