|
| 1 | +--- |
| 2 | +language: TypeScript |
| 3 | +lang: uk-ua |
| 4 | +contributors: |
| 5 | + - ["Philippe Vlérick", "https://github.com/pvlerick"] |
| 6 | + - ["Kiwimoe", "https://github.com/kiwimoe"] |
| 7 | +translators: |
| 8 | + - ["Illia Piskurov", "https://github.com/illia-piskurov"] |
| 9 | +filename: learntypescript-ua.ts |
| 10 | +--- |
| 11 | + |
| 12 | +TypeScript - це мова, яка має на меті полегшити розробку великомасштабних додатків, написаних на JavaScript. |
| 13 | +TypeScript додає загальні концепції, такі як класи, модулі, інтерфейси, узагальнене програмування та |
| 14 | +(необов'язково) статичну типізацію до JavaScript. Вона є надмножиною JavaScript: увесь код JavaScript є дійсним |
| 15 | +кодом TypeScript, тому його можна легко додати до будь-якого проекту. Компілятор TypeScript генерує JavaScript. |
| 16 | + |
| 17 | +Ця стаття концентрується тільки на синтаксисі TypeScript, на відміну від статті про [JavaScript](../javascript-ua/). |
| 18 | + |
| 19 | +Для тестування компілятора TypeScript перейдіть по посиланню в [пісочницю](https://www.typescriptlang.org/Playground). |
| 20 | +Там ви маєте змогу написати код (з підтримкою автодоповнення) та одразу побачити згенерованний JavaScript код. |
| 21 | + |
| 22 | +```ts |
| 23 | +// TypeScript має 3 базові типи |
| 24 | +var isDone: boolean = false; |
| 25 | +var lines: number = 42; |
| 26 | +var name: string = "Андерс"; |
| 27 | + |
| 28 | +// Тип «any» для випадків, коли заздалегідь невідомий тип змінної |
| 29 | +var notSure: any = 4; |
| 30 | +notSure = "або, можливо, рядок"; |
| 31 | +notSure = false; // або логічний тип |
| 32 | + |
| 33 | +// Для колекцій є типізовані та узагальнені масиви |
| 34 | +var list: number[] = [1, 2, 3]; |
| 35 | +// Альтернатива з використанням узагальненого масиву |
| 36 | +var list: Array<number> = [1, 2, 3]; |
| 37 | + |
| 38 | +// Перелік: |
| 39 | +enum Color {Red, Green, Blue}; |
| 40 | +var c: Color = Color.Green; |
| 41 | + |
| 42 | +// Зрештою, «void» використовується для позначення того, що функція нічого не повертає |
| 43 | +function bigHorribleAlert(): void { |
| 44 | + alert("Я маленьке надокучливе віконечко!"); |
| 45 | +} |
| 46 | + |
| 47 | +// Функції — це об'єкти першого класу. Вони підтримують лямбда-синтаксис (=>) |
| 48 | +// і використовують виведення типів (type inference) |
| 49 | + |
| 50 | +// Наступні рядки коду є еквівалентними, компілятором передбачається |
| 51 | +// однакова сигнатура, на виході генерується однаковий JavaScript-код |
| 52 | +var f1 = function(i: number): number { return i * i; } |
| 53 | +// Передбачається тип, що повертається |
| 54 | +var f2 = function(i: number) { return i * i; } |
| 55 | +var f3 = (i: number): number => { return i * i; } |
| 56 | +// Передбачається тип, що повертається |
| 57 | +var f4 = (i: number) => { return i * i; } |
| 58 | +// Передбачається тип, що повертається, в однорядковій функції ключове слово «return» не потрібне |
| 59 | +var f5 = (i: number) => i * i; |
| 60 | + |
| 61 | +// Інтерфейси є структурними; усе, що має властивості, сумісне з інтерфейсом |
| 62 | +interface Person { |
| 63 | + name: string; |
| 64 | + // Опціональні властивості, позначені символом «?» |
| 65 | + age?: number; |
| 66 | + // І, звісно, функції |
| 67 | + move(): void; |
| 68 | +} |
| 69 | + |
| 70 | +// Об'єкт, який реалізує інтерфейс «Person» |
| 71 | +// До нього можна звертатися, як до «Person», оскільки він має властивості «name» і «move» |
| 72 | +var p: Person = { name: "Боббі", move: () => {} }; |
| 73 | +// Об'єкти, які можуть мати опціональні властивості: |
| 74 | +var validPerson: Person = { name: "Боббі", age: 42, move: () => {} }; |
| 75 | +// Це не «Person», оскільки «age» не є числовим значенням |
| 76 | +var invalidPerson: Person = { name: "Боббі", age: true }; |
| 77 | + |
| 78 | +// Інтерфейси можуть також описувати функціональний тип |
| 79 | +interface SearchFunc { |
| 80 | + (source: string, subString: string): boolean; |
| 81 | +} |
| 82 | +// Важливі лише типи параметрів, імена — ні. |
| 83 | +var mySearch: SearchFunc; |
| 84 | +mySearch = function(src: string, sub: string) { |
| 85 | + return src.search(sub) != -1; |
| 86 | +} |
| 87 | + |
| 88 | +// Класи. Члени класу за замовчуванням є публічними |
| 89 | +class Point { |
| 90 | + // Властивості |
| 91 | + x: number; |
| 92 | + |
| 93 | + // Конструктор — ключові слова public/private у цьому контексті згенерують |
| 94 | + // шаблонний код для властивості та для ініціалізації в конструкторі |
| 95 | + // У цьому прикладі «y» буде визначено так само, як і «x», але з меншим обсягом коду |
| 96 | + // Значення за замовчуванням також підтримуються |
| 97 | + |
| 98 | + constructor(x: number, public y: number = 0) { |
| 99 | + this.x = x; |
| 100 | + } |
| 101 | + |
| 102 | + // Функції |
| 103 | + dist() { return Math.sqrt(this.x * this.x + this.y * this.y); } |
| 104 | + |
| 105 | + // Статичні члени |
| 106 | + static origin = new Point(0, 0); |
| 107 | +} |
| 108 | + |
| 109 | +var p1 = new Point(10 ,20); |
| 110 | +var p2 = new Point(25); // y буде дорівнювати 0 |
| 111 | + |
| 112 | +// Наслідування |
| 113 | +class Point3D extends Point { |
| 114 | + constructor(x: number, y: number, public z: number = 0) { |
| 115 | + super(x, y); // Явний виклик конструктора базового класу обов'язковий |
| 116 | + } |
| 117 | + |
| 118 | + // Перевизначення |
| 119 | + dist() { |
| 120 | + var d = super.dist(); |
| 121 | + return Math.sqrt(d * d + this.z * this.z); |
| 122 | + } |
| 123 | +} |
| 124 | + |
| 125 | +// Модулі, знак «.» може використовуватися як роздільник для позначення підмодулів |
| 126 | +module Geometry { |
| 127 | + export class Square { |
| 128 | + constructor(public sideLength: number = 0) { |
| 129 | + } |
| 130 | + area() { |
| 131 | + return Math.pow(this.sideLength, 2); |
| 132 | + } |
| 133 | + } |
| 134 | +} |
| 135 | + |
| 136 | +var s1 = new Geometry.Square(5); |
| 137 | + |
| 138 | +// Локальний псевдонім для посилання на модуль |
| 139 | +import G = Geometry; |
| 140 | + |
| 141 | +var s2 = new G.Square(10); |
| 142 | + |
| 143 | +// Узагальнене програмування |
| 144 | +// Класи |
| 145 | +class Tuple<T1, T2> { |
| 146 | + constructor(public item1: T1, public item2: T2) { |
| 147 | + } |
| 148 | +} |
| 149 | + |
| 150 | +// Інтерфейси |
| 151 | +interface Pair<T> { |
| 152 | + item1: T; |
| 153 | + item2: T; |
| 154 | +} |
| 155 | + |
| 156 | +// І функції |
| 157 | +var pairToTuple = function<T>(p: Pair<T>) { |
| 158 | + return new Tuple(p.item1, p.item2); |
| 159 | +}; |
| 160 | + |
| 161 | +var tuple = pairToTuple({ item1:"Привіт", item2:"Світ"}); |
| 162 | + |
| 163 | +// Включення посилання на файл визначення: |
| 164 | +/// <reference path="jquery.d.ts" /> |
| 165 | + |
| 166 | +// Шаблонні рядки (Template Strings) (рядки, які використовують зворотні лапки) |
| 167 | +// Інтерполяція рядків за допомогою шаблонних рядків |
| 168 | +let name = 'Тайрон'; |
| 169 | +let greeting = `Привіт ${name}, як ся маєш?` |
| 170 | +// Багаторядкові рядки за допомогою шаблонних рядків |
| 171 | +let multiline = `Це приклад |
| 172 | +багаторядкового рядку`; |
| 173 | + |
| 174 | +// READONLY: Нова функція у TypeScript 3.1 |
| 175 | +// Члени, які доступні лише для читання |
| 176 | +interface Person { |
| 177 | + readonly name: string; |
| 178 | + readonly age: number; |
| 179 | +} |
| 180 | + |
| 181 | +var p1: Person = { name: "Тайрон", age: 42 }; |
| 182 | +p1.age = 25; // Помилка, p1.age є тільки для читання |
| 183 | + |
| 184 | +var p2 = { name: "Джон", age: 60 }; |
| 185 | +var p3: Person = p2; // Ок, тільки для читання через псевдонім p2 |
| 186 | +p3.age = 35; // Помилка, p3.age є тільки для читання |
| 187 | +p2.age = 45; // Ок, але також змінює p3.age через псевдонім |
| 188 | + |
| 189 | +class Car { |
| 190 | + readonly make: string; |
| 191 | + readonly model: string; |
| 192 | + readonly year = 2018; |
| 193 | + |
| 194 | + constructor() { |
| 195 | + this.make = "Unknown Make"; // Присвоєння дозволено у конструкторі |
| 196 | + this.model = "Unknown Model"; // Присвоєння дозволено у конструкторі |
| 197 | + } |
| 198 | +} |
| 199 | + |
| 200 | +let numbers: Array<number> = [0, 1, 2, 3, 4]; |
| 201 | +let moreNumbers: ReadonlyArray<number> = numbers; |
| 202 | +moreNumbers[5] = 5; // Помилка, елементи тільки для читання |
| 203 | +moreNumbers.push(5); // Помилка, метод push відсутній (оскільки він змінює масив) |
| 204 | +moreNumbers.length = 3; // Помилка, довжина тільки для читання |
| 205 | +numbers = moreNumbers; // Помилка, відсутні методи для зміни масиву |
| 206 | + |
| 207 | +// Tagged Union Types для моделювання стану, що може мати одну з кількох форм |
| 208 | +type State = |
| 209 | + | { type: "завантаження" } |
| 210 | + | { type: "успіх", value: number } |
| 211 | + | { type: "помилка", message: string }; |
| 212 | + |
| 213 | +declare const state: State; |
| 214 | +if (state.type === "успіх") { |
| 215 | + console.log(state.value); |
| 216 | +} else if (state.type === "помилка") { |
| 217 | + console.error(state.message); |
| 218 | +} |
| 219 | + |
| 220 | +// Template Literal Types |
| 221 | +// Використовуються для створення складних типів рядків |
| 222 | +type OrderSize = "Звичайне" | "Велике"; |
| 223 | +type OrderItem = "Еспресо" | "Капучино"; |
| 224 | +type Order = `${OrderSize} ${OrderItem}`; |
| 225 | + |
| 226 | +let order1: Order = "Звичайне Капучино"; |
| 227 | +let order2: Order = "Велике Еспресо"; |
| 228 | +let order3: Order = "Маленьке Капучино"; // Помилка |
| 229 | + |
| 230 | +// Ітератори та Генератори |
| 231 | + |
| 232 | +// Оператор for..of |
| 233 | +// Ітерація по списку значень об'єкта, що перебирається |
| 234 | +let arrayOfAnyType = [1, "рядок", false]; |
| 235 | +for (const val of arrayOfAnyType) { |
| 236 | + console.log(val); // 1, "рядок", false |
| 237 | +} |
| 238 | + |
| 239 | +let list = [4, 5, 6]; |
| 240 | +for (const i of list) { |
| 241 | + console.log(i); // 4, 5, 6 |
| 242 | +} |
| 243 | + |
| 244 | +// Оператор for..in |
| 245 | +// Ітерація по списку ключів об'єкта, що перебирається |
| 246 | +for (const i in list) { |
| 247 | + console.log(i); // 0, 1, 2 |
| 248 | +} |
| 249 | + |
| 250 | +// Type Assertion (Приведення типів) |
| 251 | + |
| 252 | +let foo = {} // Створення порожнього об'єкта foo |
| 253 | +foo.bar = 123 // Помилка: властивість 'bar' не існує на `{}` |
| 254 | +foo.baz = 'привіт світ' // Помилка: властивість 'baz' не існує на `{}` |
| 255 | + |
| 256 | +// Оскільки передбачуваний тип foo є `{}` (об'єкт з 0 властивостями), |
| 257 | +// не дозволяється додавати bar і baz до нього. Однак за допомогою приведення типу, |
| 258 | +// наступне пройде без помилок: |
| 259 | + |
| 260 | +interface Foo { |
| 261 | + bar: number; |
| 262 | + baz: string; |
| 263 | +} |
| 264 | + |
| 265 | +let foo = {} as Foo; // Приведення типу |
| 266 | +foo.bar = 123; |
| 267 | +foo.baz = 'привіт світ' |
| 268 | +``` |
| 269 | + |
| 270 | +## Для подальшого читання |
| 271 | + |
| 272 | +* [Офіційний веб-сайт TypeScript](https://www.typescriptlang.org/) |
| 273 | +* [Вихідний код на GitHub](https://github.com/microsoft/TypeScript) |
| 274 | +* [Вивчення TypeScript](https://learntypescript.dev/) |
0 commit comments