Type Compatibility
Type Compatibility
Сумісність типу (як ми обговорюємо тут) визначає, чи можна призначити один предмет іншому. наприклад string i number несумісні:
let str: string = "Hello";
let num: number = 123;
str = num; // ERROR: `number` is not assignable to `string`
num = str; // ERROR: `string` is not assignable to `number`Soundness
Система типів TypeScript розроблена так, щоб бути зручною та допускати unsound поведінку, напр. будь-що можна призначити будь-якому, що означає, що компілятор повинен дозволити вам робити все, що завгодно:
Structural
Об'єкти TypeScript є структурно типізованими. Це означає, що іменуванняs не мають значення, якщо структури збігаються
Це дозволяє вам створювати об’єкти на льоту (як ви це робите у vanilla JS) і залишатися в безпеці, коли це можна зробити.
Також більше даних вважається правильним
Variance
Дисперсія — це легке для розуміння та важливе поняття для аналізу сумісності типів.
Для простих типів Base і Child, якщо Child є дочірнім типом Base, тоді екземпляри Child можна призначити змінній типу Base.
Це поліморфізм 101
Сумісність типів складних типів, що складаються з таких типів Base і Child, залежить від того, де Base і Child у подібних сценаріях керуються variance.
Коваріант: (співпраця, він же спільний) тільки в спільному напрямку
Контраваріант: (контра, він же негативний) тільки вoпротилежний напрямок
Біваріант : (bi або обидва) і co, і contra.
Invariant : якщо типи не зовсім однакові, вони несумісні.*
Примітка: для повністю надійної системи за наявності змінних даних, таких як JavaScript,
invariantє єдиним дійсним варіантом. Але, як уже згадувалося, зручність змушує нас робити необґрунтований вибір.
Functions
Порівнюючи дві функції, слід враховувати кілька тонких моментів.
Return Type
covariant: тип повернення має містити принаймні достатньо даних.
Number of arguments
Менша кількість аргументів — це добре (тобто функції можуть ігнорувати додаткові параметри). Адже вам гарантовано викличете їх із як мінімум достатніми аргументами.
Optional and Rest Parameters
Необов’язкові (попередньо визначена кількість) і параметри Rest (будь-яка кількість аргументів) сумісні, знову ж для зручності.
Примітка: необов’язковий (у нашому прикладі
bar) і необов’язковий (у нашому прикладіfoo) сумісні, лише якщо strictNullChecks має значення false.
Types of arguments
bivariant : це розроблено для підтримки типових сценаріїв обробки подій
Крім того, Array<Child> можна призначити Array<Base> (коваріація), оскільки функції сумісні. Коваріація масиву вимагає, щоб усі функції Array<Child> можна було призначити Array<Base>, наприклад. push(t:Child) можна призначити push(t:Base), що стало можливим завдяки біваріантності аргументів функції.
Це може збити з пантелику людей, які знають інші мови, які очікували б наступного помилки, але не в TypeScript:
Enums
Enum сумісні з числами, а числа сумісні з enum.
** Значення Enum з різних типів enum вважаються несумісними. Це робить переліки придатними для використання номінально (на відміну від структурних)
Classes
Порівнюються лише члени екземпляра та методи.constructors і statics не грають ролі.
privateтаprotectedчлени повинні походити з того самого класу. Такі члени по суті роблять клас nominal.
Generics
Оскільки TypeScript має структурну систему типів, параметри типу впливають на сумісність лише тоді, коли вони використовуються членом. Наприклад, у наступному T не впливає на сумісність:
Однак, якщо використовується T, він відіграватиме роль у сумісності на основі свого екземпляру, як показано нижче:
У випадках, коли загальні аргументи не були інстанцировані, вони замінюються на any перед перевіркою сумісності:
Універсали, що включають класи, відповідають відповідній сумісності класів, як згадувалося раніше
FootNote: Invariance
Ми сказали, що інваріантність — це єдиний правильний варіант. Ось приклад, коли дисперсія contra і co небезпечна для масивів.
Last updated