TypeScript's Type System
Ми розглянули основні функції TypeScript Type System ще під час обговорення Why TypeScript?. Нижче наведено кілька ключових висновків із цієї дискусії, які не потребують додаткових пояснень:
Система типів у TypeScript розроблена як optional,так щоб your JavaScript був TypeScript.
TypeScript не блокує JavaScript emit за наявності помилок типу, дозволяючи вам поступово змінювати JS на TS.
Тепер почнемо з синтаксису системи типів TypeScript. Таким чином ви можете негайно почати використовувати ці анотації у своєму коді та побачити переваги. Це підготує вас до більш глибокого занурення пізніше.
Basic Annotations
Як згадувалося раніше, типи анотуються за допомогою синтаксису :TypeAnnotation
. Усе, що є в просторі оголошення типу, можна використовувати як анотацію типу.
У наступному прикладі демонструються анотації типів для змінних, параметрів функції та значень, що повертаються функцією:
Primitive Types
Примітивні типи JavaScript добре представлені в системі типів TypeScript. Це означає string
, number
, boolean
, як показано нижче:
Arrays
TypeScript надає спеціальний синтаксис типів для масивів, щоб полегшити вам коментування та документування коду. Синтаксис в основному полягає в постфіксі []
до будь-якої дійсної анотації типу (наприклад, :boolean[]
). Це дозволяє безпечно виконувати будь-які маніпуляції з масивом, які ви робите зазвичай, і захищає вас від помилок, таких як призначення члену неправильного типу. Це показано нижче:
Interfaces
Інтерфейси є основним способом у TypeScript створювати кілька анотацій типів в одну анотацію з іменем. Розглянемо такий приклад:
Тут ми скомпонували анотації first: string
+ second: string
у нову анотацію Name
, яка забезпечує перевірку типу для окремих членів. Інтерфейси мають велику силу в TypeScript, і ми присвятимо цілий розділ тому, як ви можете використовувати це на свою користь.
Inline Type Annotation
Замість створення нового інтерфейсу
ви можете анотувати все, що забажаєте inline за допомогою :{ /*Structure*/ }
. Попередній приклад знову представлений із вбудованим типом:
Вбудовані типи чудово підходять для швидкого надання одноразової анотації типу для чогось. Це позбавить вас від клопоту придумати (потенційно погану) назву типу. Проте, якщо ви виявите, що вставляєте анотацію того самого типу в рядок кілька разів, доцільно розглянути можливість рефакторингу її в інтерфейс (або type alias
розглянутий далі в цьому розділі).
Special Types
Крім примітивних типів, які були розглянуті, є кілька типів, які мають особливе значення в TypeScript. Це any
, null
, undefined
, void
.
any
Тип any
займає особливе місце в системі типів TypeScript. Це дає вам вихід із системи типів, щоб наказати компілятору відключитися. any
сумісний з any and all типами в системі типів. Це означає, що anything can be assigned to it і it can be assigned to anything. Це показано на прикладі нижче:
Якщо ви переносите код JavaScript на TypeScript, на початку ви будете близькими друзями з any
. Однак не сприймайте цю дружбу надто серйозно, оскільки це означає, що це залежить від вас, щоб забезпечити безпеку типу. По суті, ви наказуєте компілятору не робити значущого статичного аналізу.
null
and undefined
null
and undefined
Те, як вони обробляються системою типів, залежить від прапора компілятора strictNullChecks
(ми розглянемо цей прапор пізніше). У strictNullCheck:false
літерали JavaScript null
і undefined
ефективно обробляються системою типів так само, як щось типу any
. Ці літерали можна віднести до будь-якого іншого типу. Це показано на прикладі нижче:
:void
:void
Використовуй :void
як прапор, що функция не повертає значення:
Generics
Багато алгоритмів і структур даних в інформатиці не залежать від актуального type об’єкта. Однак ви все одно хочете застосувати обмеження між різними змінними. Простий приклад — це функція, яка приймає список елементів і повертає перевернутий список елементів. Тут існує обмеження між тим, що передається у функцію, і тим, що функція повертає:
Тут ви в основному говорите, що функція reverse
приймає масив (items: T[]
) будь-який типу T
(зверніть увагу на параметр типу в reverse<T>
) і повертає масив типу T
(примітка : T[]
). Оскільки функція reverse
повертає елементи того самого типу, що й приймає, TypeScript знає, що змінна reversed
також має тип number[]
і забезпечить вам захист від типу. Подібним чином, якщо ви передаєте масив string[]
до зворотної функції, повернутий результат також буде масивом string[]
, і ви отримаєте подібну безпеку типу, як показано нижче:
Насправді масиви JavaScript вже мають функцію .reverse
, і TypeScript справді використовує загальні коди для визначення своєї структури:
Це означає, що ви отримуєте безпеку типу під час виклику .reverse
для будь-якого масиву, як показано нижче:
Ми обговоримо більше про інтерфейс Array<T>
пізніше, коли представимо lib.d.ts
у розділі Ambient Declarations.
Union Type
Досить часто в JavaScript ви хочете дозволити властивості бути одним із кількох типів, наприклад. a string
or a number
. Тут стане в нагоді обʼєднаний type (позначений |
в анотації типу, наприклад string|number
). Загальним варіантом використання є функція, яка може приймати один об’єкт або масив об’єктів, наприклад:
Intersection Type
extend
— це дуже поширений шаблон у JavaScript, де ви берете два об’єкти та створюєте новий, який має функції обох цих об’єктів. Intersection Type дозволяє безпечно використовувати цей шаблон, як показано нижче:
Tuple Type
JavaScript не підтримує першокласний кортеж. Люди зазвичай просто використовують масив як кортеж. Це саме те, що підтримує система типів TypeScript. Кортежі можна анотувати за допомогою : [typeofmember1, typeofmember2]
тощо. Кортеж може мати будь-яку кількість елементів. Кортежі демонструються в наведеному нижче прикладі:
Поєднайте це з підтримкою деструктуризації в TypeScript, кортежі виглядатимуть як першокласні, незважаючи на те, що вони є масивами:
Type Alias
TypeScript забезпечує зручний синтаксис для надання імен для анотацій типів, які ви хотіли б використовувати в кількох місцях. Псевдоніми створюються за допомогою синтаксису type SomeName = someValidTypeAnnotation
. Нижче наведено приклад:
На відміну від interface
, ви можете надати псевдонім типу буквально будь-якій анотації типу (корисно для таких речей, як типи об’єднання та перетину). Ось ще кілька прикладів, щоб ви ознайомилися з синтаксисом:
ПОРАДА: якщо вам потрібні ієрархії анотацій типу, використовуйте
interface
. Їх можна використовувати зimplements
іextends
ПОРАДА: Використовуйте псевдонім типу для простіших структур об’єктів (наприклад,
Coordinates
), щоб дати їм семантичну назву. Крім того, якщо ви хочете дати семантичні назви типам Union або Intersection, використовуйте псевдонім типу.
Summary
Тепер, коли ви можете почати анотувати більшу частину свого коду JavaScript, ми можемо перейти до найдрібніших деталей усієї потужності, доступної в системі типів TypeScript.
Last updated