Essенцыя TypeScript: Практычныя нараджэнні для разработчыкаў JavaScript
TypeScript для разработчыкаў JavaScript: практычны курс — базовыя типы, tsconfig, режым строгасці, а таксама паследоўны шлях міграцыі, які робіць код болей безпечным для змены пазней.
Крыніцы: TypeScript for JavaScript Developers: A Practical Beginner’s Guide
Якщо вы вже знаеце JavaScript, опанаванне TypeScript адчуваецца не як выучэнне абсалютна новага мовы, а скорей як расшырэнне той, яку вы вже розумеете.
TypeScript — это, по суцэйству, JavaScript з дадзеным системай типаў, якая дадана ў яго як дапаможнае шароўдзе.
Вы продовжаеце працаваць з зменнымі, функцыямі, масавымі значэннямі, об’ектамі, класамі, праграмамі, моделямі async/await і практычна з усім іншым, што вам вже знайома. TypeScript прыносіць набор адзінакоў, якія выловляюць аберанні рана, яшчэ перш чым ваш код запускаецца ў браузеры або на серверы.
У гэтым кяліку прадстаўлены самыя важлівыя концэпты TypeScript для разработчыкаў, якія вже пішуць на JavaScript.
Што такое TypeScript?
TypeScript — это мова, якая дадана ў JavaScript як дапаможнае шароўдзе.
У большасці случаў любая програма на JavaScript, яку вы напісалі, таксама ўважаецца валідным кодам на TypeScript. Тыповыя функцыі дадаюць статычную перапакоўку типаў, і ў канцэ наступнае компіляванне прыводзіць да стандартнага JavaScript, які запускаецца ў браузерах і на Node.js.
Вазьмімо як прыклад гэты просты фрагмент коду на JavaScript:
function add(a, b) {
return a + b;
}
Праўернуты на TypeScript, той самы функцыя можа заявіць, якія типы значэнняў ён прыме:
function add(a: number, b: number): number {
return a + b;
}
Разбіраючы гэта далей:
a: numberвымагае, кабaбыў числам.b: numberвымагае, кабbбыў числам.- Заканчыцца
: numberзаявляе, што значэнне, якое вяртае функцыя, є числам.
За дапамогай гэтых анотацый TypeScript можа пазначыць некоректны вызов функцыі ўжо перад пачаткам експанацыі:
add(10, 20); // Correct
add("10", "20"); // TypeScript error
У звычнам JavaScript, калі вызваць функцыю з аргументамі-строкамі, яна будзе тылу незазначана вяртаць "1020", таму што аператар плюса будзе скалакаваць строкі заместо аддыявання числаў. TypeScript выловляе такую неняхучую працэзу ў пачатку.
Чаму вжываць TypeScript?
Гнучкасць JavaScript — гэта яго сіла, але ёна таксама можа стварыць падставы для тонкіх багоў.
Возьмімо гэтую функцыю як прыклад:
function calculateDiscount(price, percentage) {
return price - price * percentage / 100;
}
Яе правільны вызов працюе як і чакалася:
calculateDiscount(1000, 10);
Але нічога не заважае вызваць яе так:
calculateDiscount("1000", "ten");
Проблема пазнаёцца толькі тады, калі код фактычна выкананы.
За дапамогою TypeScript можна задаць типы, якія функцыя чакае:
function calculateDiscount(
price: number,
percentage: number
): number {
return price - price * percentage / 100;
}
Тепер TypeScript адразу пазначае некоректныя аргументы, не трэба спачатку запускать код.
Калькольныя прыемніцы, якія гэта дае, включаюць:
- Автадыягаванне памылак праз тое, што вы яшчэ запісвайце код
- Павышаная падтрымка автадыягавання ў вашам рэдагаре
- Простыяй і безпечнейшы рефакторынг
- Более чысткія форматы функцый і об’ектаў
- Кращая саавершанасць у працы над большымі кодавымі базамі
- Тыпы, якія выступаюць у ролі вбудованай дакументацыі
Ценнасць TypeScript становіцца ўсё бол ясной, калі проект вырастае за межы калькольных файлоў або ў яму беруць участь больш за аднаго разрабоўца.
Інсталяванне TypeScript
TypeScript можна інсталаваць глобальна за дапамогою:
npm install -g typescript
Ёсць паўтарыць версію, якая была інсталавана, запусціце:
tsc --version
Потым створыце файл пад назвай:
app.ts
Да яго дадзіце некалькі кода на TypeScript:
const message: string = "Hello TypeScript";
console.log(message);
Компілюйце файл за дапамогою:
tsc app.ts
Гэта дае компільаваны выхадны JavaScript:
app.js
Рэзультат можна запусціць безпасова з Node.js:
node app.js
У прымэтных сетапах інструменты та фреймворкі, такія як React, Next.js, Angular і NestJS, зазвычай автаматычна абараняюцься заціхоўкай для вас.
Файл tsconfig.json
Большасць проектаў на TypeScript выкарыстовае файл tsconfig.json для налаштавання кампіляра.
Яго можна стварыць за дапамою:
tsc --init
Мінімальная налаштавання можа выглядаць так:
{
"compilerOptions": {
"target": "ES2020",
"module": "ESNext",
"strict": true,
"outDir": "./dist",
"rootDir": "./src"
}
}
Ёсць калькі з наўжоўткавейшых налаштаўкаў:
target
Гэта кантролюе, якую версію JavaScript выдае кампіляр.
"target": "ES2020"
module
Гэта задае формат модуля, які выкарыстоўваецца у скомпіляваным рэзультате.
"module": "ESNext"
strict
Як толькі гэта увёмкнуцца, будзе актываўвацца адносна строгія рэгламентацыя перакантролю типаў.
"strict": true
Для кожнага новага проекту настойчыва рэкамендуецца залішыць режым строгасці увёмкнутым.
rootDir
Гэта паведамляе кампайлеру, дзе знаходзяцца вашы файлы-выканніка TypeScript.
"rootDir": "./src"
outDir
Гэта вялічына паказвае, дзе трэба запісваць скомпіляваны выканнік на JavaScript.
"outDir": "./dist"
Базовыя типы
У TypeScript є калькольныя типы, якія вам вядомы.
Строка
let username: string = "Vijeet";
Чысла
let experience: number = 10;
TypeScript не розлічвае цэлыя числа і числа з плаваючай канматой; оба належаць да типу number.
let age: number = 35;
let price: number = 999.99;
Логічныя значэння
let isActive: boolean = true;
Null і Undefined
let emptyValue: null = null;
let missingValue: undefined = undefined;
У режыме строгай працы вам патрэбна будзе адказальнейшая обработка значэнняў null і undefined.
Аўтадыферэнція типаў
Вам не трэба ручна атрыбутаваць кожнае значэнне.
TypeScript часта можа вывучыць тип зменнай на адной падставе таго, што ёй прызначаецца.
let city = "Ahmedabad";
Хутчэй TypeScript аўтаматычна вывучае, што city — это строка.
Прабаўка перазначыць яе так спрычыніць кэсю:
city = 100;
Тут прыменяецца тая ж логіка:
let total = 500;
TypeScript вывучае, што total храніць число.
Апоўзка на аўтадыферэнцію дапамагае захаваць код чыстым. Заказваюцься явныя атрыбуты типаў там, дзе яны справяюць рэальную яснасць, напрыклад для параметраў функцый, формату адпаведзей API і болей складных структураў об’ектаў.
Масівы
Ось звычны масів у JavaScript:
const skills = ["JavaScript", "React", "Node.js"];
TypeScript дазваляе анотаваць тип элемента масів:
const skills: string[] = [
"JavaScript",
"React",
"Node.js"
];
Яго таксама можна запісаць за дапамою генерычнай синтаксі:
const skills: Array<string> = [
"JavaScript",
"React",
"Node.js"
];
Тая ж ідея прыменшаецца да числовых масав:
const scores: number[] = [75, 82, 91];
TypeScript блакуе будзь-якія спробы адключыць значэнне неправильнага типу:
scores.push(95); // Correct
scores.push("ninety"); // Error
Об’екты
Можна даць звычны ў JavaScript об’ект спецыяльную структуру.
const user: {
name: string;
age: number;
isAdmin: boolean;
} = {
name: "Vijeet",
age: 35,
isAdmin: true
};
Якщо якась-небудзь властыбе не існуе або мае неправильны тип, TypeScript пазначае гэта як адзін з бягов.
const user: {
name: string;
age: number;
} = {
name: "Vijeet"
};
Хутчэй, неабходная властыбе age не ўключана ў об’ект.
Калі трэба павтараць тую ж структуру об’екта ў калькі месцаў, інтэрфейсы або псевдонімы типаў є кращым выкарыстоўваннем, чым пісаць структуру кожны раз занова.
Інтэрфейсы
Інтэрфейс визначае структуру, якой павінен матыць об’ект.
interface User {
id: number;
name: string;
email: string;
isActive: boolean;
}
Пасля ўзначэння гэтую інтарфейс можна перадаць знову ў будзь-ям месца:
const user: User = {
id: 1,
name: "Vijeet",
email: "vijeet@example.com",
isActive: true
};
Інтарфейсы становяцься карыстнымі у такіх ситуацыях:
- опісве запісаных дакументаў пользователя
- моделюванні элемента каталогу
- перакананні ў правямоце заполненых поль у форме
- формаванні даных, якія вяртаюцца з вызову API
- вызначэнні параметраў, якія пасылаюцца да компонента
- прадстаўленні рэкорда з табелі базы дадзенаў
Напрыклад:
interface Product {
id: number;
title: string;
price: number;
}
Функцыя можа прыймаць Product як параметр:
function displayProduct(product: Product): void {
console.log(`${product.title}: ₹${product.price}`);
}
Необавязковыя атрыбуты
Дэйнькія атрыбуты об’екта не завжды будуць наявны.
Ўсім іх пазначаюць, дадаўшы знак запытання пасля імені атрыбута:
interface User {
id: number;
name: string;
phone?: string;
}
Оба следуючыя об’екты падтрымліваюць даны інтарфейс:
const userOne: User = {
id: 1,
name: "Amit"
};
const userTwo: User = {
id: 2,
name: "Neha",
phone: "9876543210"
};
Паколькі phone ўзельгварны, яго тип стае:
string | undefined
Это значыць, што трэба пераканацца, чы ён існуе, прытымкі яго выкарыстоўваць:
if (userTwo.phone) {
console.log(userTwo.phone);
}
Аліясы типаў
Аліяс типа дазволяе прызначыць імэну, якое можна выкарыстоўваць знова, будзь-каму типу.
type UserId = number;
Пасля чаго можна выкарыстоўваць гэты аліяс як тип:
const id: UserId = 101;
Аліясы типаў особліва корыстныя пад час апісання юнійнаў або болей складных комбінацыяў типаў.
type Status = "pending" | "approved" | "rejected";
З гэтым аліясам дазволены толькі тры конкрэтныя строкі:
let applicationStatus: Status = "pending";
Якшо спробаваць ўсё іншае, будзе выклікана памылка:
applicationStatus = "completed";
Інтэфейсы протыва аліясаў типаў
І інтэфейсы, і аліясы типаў можу моделюваць структуру об’екта.
Ось версія з інтэфейсам:
interface Customer {
name: string;
email: string;
}
І адпаведная версія з аліясам типаў:
type Customer = {
name: string;
email: string;
};
Як апрынтовая правіла для новачкаў:
- Выбірайце
interface, калі описваеце об’екты чыста класоў. - Выбірайце
type, калі працуеце з аб’еднаннямі, псевдонімамі для прымітываў, тупламі чыста болей складнымі сумаванымі типамі.
Аднак гэта не ўсёвыключна строгая правіла — у багатох случаях аба падходы працуюць на однакова хораша.
Аб’еднаныя типы
Аб’еднаны тип дазволяе значэнню прымаць адны з кальколькі можлівых типаў.
let userId: string | number;
Оба гэтыя прызначэння ўсуненія:
userId = 101;
userId = "USR-101";
Аб’еднаныя типы ўжыткавы, калі даны, якія прыходзяць з рэальнага свету, не завжды павінны адпавядаць аднаму фіксаванаму формату.
function printId(id: string | number): void {
console.log(id);
}
Перад вызывам метода, які існуе толькі для адного з можлівых типаў, спачатку трэба сузіць значэнне:
function printId(id: string | number): void {
if (typeof id === "string") {
console.log(id.toUpperCase());
} else {
console.log(id.toFixed(0));
}
}
Гэтыя тэхнікі называюцца сузаванням типаў.
Літэральныя типы
Літеральныя типы обмежваюць зменную точным, заздалега вялікім наборам значэнняў.
type Theme = "light" | "dark" | "system";
Такая прызначэнне ўсё гаразд:
let selectedTheme: Theme = "dark";
Але такая прызначэнне адхіляецца:
selectedTheme = "blue";
Літеральныя типы ўзгоднае рашэнне для такіх случаў:
- тэкучы статус записі
- рэвалюцыя прав, прызначаная корыстніку
- настройкі візуальнага тэмы
- візуальны стыль кантакту
- HTTP-дзеянне, якое выкарыстоўваецца у запытэ
- режым, у якім работае прыкладнэц
Як прыклад:
type UserRole = "admin" | "editor" | "customer";
Функціі
Для параметраў функцыі тип пісаецца ведама пасля імені параметра.
function greet(name: string): string {
return `Hello, ${name}`;
}
Тып вярнення функцыі пісаецца пасля заканчальнай складкіяў списку параметраў.
function multiply(a: number, b: number): number {
return a * b;
}
Калі функцыя не вяртае значэнне, адзначыце яе словам void.
function logMessage(message: string): void {
console.log(message);
}
Необавязковыя параметры пазначаюцца з ?:
function greetUser(
name: string,
title?: string
): string {
if (title) {
return `Hello, ${title} ${name}`;
}
return `Hello, ${name}`;
}
Значэння стандартных параметраў працуюць так сама, як і ў звычнам JavaScript:
function calculateTax(
amount: number,
rate: number = 18
): number {
return amount * rate / 100;
}
Тыпаванне функцый-стрэлкі
Функцыі-стрэлкі можна анотаваць так сама.
const subtract = (
a: number,
b: number
): number => {
return a - b;
};
Ёсць болей компактны формат:
const subtract = (
a: number,
b: number
): number => a - b;
Тып any
Пазначэнне тыпу any значэнню прыводзіць да таго, што TypeScript перастае яго перакантролювачы.
let data: any = "Hello";
data = 100;
data = true;
data = { name: "Vijeet" };
Хоць спачатку гэта можа здавацца зручным, частая адналежнасць да any паскладжвае большую частку таго, што пропонуе TypeScript.
Возьмімо гэты прыклад:
function processData(data: any): any {
return data.someProperty.someMethod();
}
TypeScript не можа нічога зрабіць, каб выявіць адмылкі ў гэтай функцыі.
Застосавайце any толькі у ситуацыях, калі гэта дасправды немагчыма адвакацыйна — напрыклад, пад час поступовай перакантраванні базы коду на JavaScript, або калі працуеце з дадзеннямі трэціх сторон, якія не маюць правильных адзначэнняў типу.
Тып unknown
unknown дае вам болей безпечны спосаб представлення значэнняў, тып якіх не вядома заздалегідь.
let value: unknown;
Как і any, ён прымае любы тип значэння:
value = "Hello";
value = 100;
value = true;
Але на адзінак з any, TypeScript вымагае ад вас сузіць тип прытаманнае яго выкарыстанню:
if (typeof value === "string") {
console.log(value.toUpperCase());
}
Гэта робіць unknown падходячым для:
- Дадзенняў, якія надаюцца з зовнішніх API
- Значэнняў, парсаваных з JSON
- Об’ектаў памылак, якія ловяцца ў блоке try/catch
- Даных, якія надаюць корыстнікі
- Будзь-чаго, форма якога ўсё ще не вяліка
Асерцыі типу
Іноды у вас ёсць большае количество інфармацыі пра значэнне, чым можа сама TypeScript вывячыць.
Асэрцыя типу дазваляе вам падказаць кампайлеру, як трэба адносіцца да гэтаго значэння.
const input = document.getElementById(
"email"
) as HTMLInputElement;
Пасля асэрцыі вы можете запускацься да атрыбутаў, спецыфічных для гэтага типу:
console.log(input.value);
Памятаце, што асэрцыя нічога не зменяе ў часе выканання — яна толькі зменяе спосаб, яким TypeScript адначыта значэнне пад час кампайлірацыі.
З гэтой прычыны трэба вжываць асэрцыі рэдка і толькі тады, калі вы впевнены ў фактычным формате дадзеных.
Туплы
Тупл — это масіва з адначым колікствам пазух, дзе кожна позыцыя мае свой вядомы тип.
let userEntry: [number, string];
userEntry = [1, "Vijeet"];
У гэтым случае першая пазуха должна мяць число, а другая — строку.
Наступны варыянт не будзе працаваць:
userEntry = ["Vijeet", 1];
Туплы чудова падаюць для малых, фіксаванага формата дадзенняў або парных значэнняў:
type Coordinate = [number, number];
const location: Coordinate = [23.0225, 72.5714];
Калі вашы дадзеныя становяцца болей складнымі або патрабуеюць описавых імен полей, звычныя об’екты заўсёды є болей зрозумелымі.
Enums
Enum дазволяе вам задаць фіксаваную групу іменаванных сталярых значэнняў.
enum OrderStatus {
Pending,
Processing,
Shipped,
Delivered
}
Вы можете згадваць іх так:
let status: OrderStatus = OrderStatus.Processing;
Заставленне enum стрэлкавых значэнняў часта паспяшае чытаемасць:
enum PaymentStatus {
Pending = "pending",
Paid = "paid",
Failed = "failed"
}
Пры тым, багато корыстнікаў TypeScript вяртаюцца да типаў-уній, усабліва для простыях сцэнарыёў:
type PaymentStatus =
| "pending"
| "paid"
| "failed";
Тыпы-уній зазвычай кампілююцца ў меншы выхідны JavaScript і являюцься надзеяным стандартам для большасці коду фронт-энду.
Класы
TypeScript расшырюе звычныя класы JavaScript за дапамогою пераканальвання типаў.
class Employee {
name: string;
salary: number;
constructor(name: string, salary: number) {
this.name = name;
this.salary = salary;
} getAnnualSalary(): number {
return this.salary * 12;
}
}
Стварэнне экземпляра класа выглядае так сама, як і ў JavaScript:
const employee = new Employee("Rahul", 50000);
console.log(employee.getAnnualSalary());
Модифікаторы доступу таксама ўскладнююць синтаксі класаў у TypeScript.
class BankAccount {
public accountHolder: string;
private balance: number;
constructor(accountHolder: string, balance: number) {
this.accountHolder = accountHolder;
this.balance = balance;
} public getBalance(): number {
return this.balance;
}
}
Главныя модифікаторы ўключаюць:
public: видны з будзь-якага месцаprivate: видны толькі внутрь самага класаprotected: видны внутрь класа і ў яго падкласахreadonly: можа быць заданы ўсёраз, але пасля чаго не можа быць зменены
Генерыкі
Генерыкі дазволяюць пісаць гнучкі, повторна викорыстоўваны код, який пры тым захоўвае полную безпеку типаў для разных типаў дадзеных.
Возьміце гэтую функцыю як вачоўку:
function returnValue(value: any): any {
return value;
}
Паколькі яна выкарыстоўвае any, TypeScript не можа сказаць вам ніч пра тое, што будзе выходзіць з яе.
Перапісаванне коду з викорыстаннем генерычнага параметра выправляе гэта:
function returnValue<T>(value: T): T {
return value;
}
Теперы тип вяртання падобаецца таму, што было передана:
const text = returnValue<string>("Hello");
const count = returnValue<number>(100);
У багатых случаях TypeScript можа автаматычна вывучыць генерычны тип, таму не трэба яго пісаць вручную:
const text = returnValue("Hello");
const count = returnValue(100);
Генерыкі постаюць стало пад час работы з масавымі, формамі адпаведзей API, повтарна выкорыстоўванымі компонентамі UI, спецыяльнымі хукамі і дапаможнімі функцыямі.
function getFirstItem<T>(items: T[]): T | undefined {
return items[0];
}
Выводзіцца так:
const firstNumber = getFirstItem([10, 20, 30]);
const firstName = getFirstItem(["Amit", "Neha"]);
Promise'ы і асінхронныя функцыі
Функцыі, адзячаныя з async, завжды вяртаюць promise'ы.
async function getUsername(): Promise<string> {
return "Vijeet";
}
Асінхронная функцыя, якая вяртае об’ект корыстніка, можа выглядаць так:
interface User {
id: number;
name: string;
}
async function getUser(): Promise<User> {
return {
id: 1,
name: "Vijeet"
};
}
А для спісу корыстнікаў тип вяртання трэба пакаваць у масу:
async function getUsers(): Promise<User[]> {
return [
{ id: 1, name: "Vijeet" },
{ id: 2, name: "Rahul" }
];
}
Такы спосаб прызначэння правильных типаў для рэсультатаў API заходзіць рэшту вашага кодбазы ад памылак у пасляэтапным выкарыстоўванні.
Задача типаў для адпаведзяў API
Уявіце тэрмінал, які вяртае звісткі пра тавары:
interface Product {
id: number;
title: string;
price: number;
}
Вы можете абгорнуць вызов fetch у функцыю, якая прызначае тип ўзврату:
async function fetchProducts(): Promise<Product[]> {
const response = await fetch("/api/products");
if (!response.ok) {
throw new Error("Unable to fetch products");
} const data: Product[] = await response.json(); return data;
}
Есць адзін момент, які варта памятаць: TypeScript не можа пераканацца ў правядзімасці гэтых дадзеных пасля таго, як прыложэнне ўжо запускаецца.
Рэчынка:
const data: Product[] = await response.json();
толькі паведамляе кампайлеру прыймаць аналізаванае адпаведзенне як Product[] — ён не паўтарае, што сервер даслаў об’екты самэй такой формы.
Для прыложэнняў, дзе важна правядзімасць, разработчыкі часта выкарыстоўваюць TypeScript разам з бібліятэкай для верыфікаціі ў часе выканання, такой як Zod, каб запалаваць гэты прыемак.
Работа з элементамі DOM
Тыпы элементаў прыгледача ўжо є у TypeScript.
const button = document.querySelector(
"#submit-button"
);
Кампайляр ведае, што гэты запыт можа вернуцца пустым, таму тип рэзультата включае null разам з типам элемента.
Это значыць, што пры выкарыстоўванні яго трэба захіцца ад ситуацыі, калі ён не існуе:
if (button) {
button.addEventListener("click", () => {
console.log("Button clicked");
});
}
Якщо вам патрэбны болей спецыфічныя типы элементаў, вы можете яго падтвердзіць:
const emailInput = document.querySelector(
"#email"
) as HTMLInputElement | null;
Потым прачытайце його значэнне, калі будзе падтверджана яго наявнасць:
if (emailInput) {
console.log(emailInput.value);
}
TypeScript не заменяе перакананне ў часе выконання
Гэты момент трэба падкресліць, асобліва для разработчыкаў, якія праішлі з JavaScript.
Перакананні TypeScript адбываюцца толькі пад час разработки і кампайлявання. Калі ваш код будзе скомпільаваны ў JavaScript, усе анотацыі типаў зникнуць.
Возьмімо гэтую функцыю:
function double(value: number): number {
return value * 2;
}
Пасля кампайлявання яна стае прыблізна такой:
function double(value) {
return value * 2;
}
У тым моманце не застаёцца жадных следоў первачальной інфармацыі пра тип, якая могла б служыць для апэлірацыі да якіх-небудзь правілаў.
У результате TypeScript не можа гарантаваць, што:
- API фактычна вернула правільна структураваныя даны
- Пользователь увёл правільную значэнне
- Запіс у базе дадзенаў паспаўдаецца ажыцоўленай структуре
- Сервіс трэцьей стороны выпалняе свой задокументаваны контракт
Усё, што прыходзіць за межамі вашага коду, яшчэ трэба пераканацца пад час выконвання програмы.
Міграцыя існуючага проекту на JavaScript
Канвертаванне базы коду на JavaScript у TypeScript не павінна вадзіцца ў адной масовай перапісве.
Пашагоўная міграцыя ў практыцы часта работае краща.
Шаг 1: Установіце TypeScript
npm install --save-dev typescript
Шаг 2: Створыце tsconfig.json
npx tsc --init
Шаг 3: Вяліканае вжыцце JavaScript
{
"compilerOptions": {
"allowJs": true,
"checkJs": false
}
}
Крок 4: Поступова замена назв файлаў
Зменіце файл так:
utils.js
на:
utils.ts
А для компанентаў React ператворыце:
Button.jsx
на:
Button.tsx
Крок 5: Вылечэнне бягаў па адны файл за раз
Дапамагае пачаць з функцый-інструментаў, спяльных модэляў дадзеных і менжых компанентаў, а болей заплутаную логіку прыкладнення заставіць на пазнейшы момент.
Гэты поступовы падход яўляецца аднам з найбольшых практычных прыямоў, якія простая мова TypeScript дае пад час ўведэння яе ў існуючы проект.
Пашырэныя памылкі, якія дзеяўцы JavaScript чыняць
Іспользованне any ў всіх месцах
const user: any = getUser();
Гэта можа затыміць негайную працоўку компайлера, але ў той жытак усунець усю перацэнку типаў.
Лепшы падход — задаць рэальны інтерфейс:
interface User {
id: number;
name: string;
}
Дадаванне типаў да кожнай зменной
Няма прычыны пісаць гэта:
const name: string = "Vijeet";
const count: number = 10;
const active: boolean = true;
такім чынам, адгукцыя типаў вже сама выканае ўзлёгчэнне з’ясавання гэтых типаў:
const name = "Vijeet";
const count = 10;
const active = true;
Заказваце явныя анотацыі толькі там, дзе яны справды дапамагаюць павышыць яснасць.
Ігнараванне null
Гэты код можа зламацца пад час выканання:
const element = document.querySelector("#app");
element.innerHTML = "Hello";
Элемент, які выкарыстоўваецца для запыту, можа проста не існаваць на сторанцы.
Замест таго захаваўся ад такой можлівасці:
const element = document.querySelector("#app");
if (element) {
element.innerHTML = "Hello";
}
Выкарыстоўванне асэрцый типаў для сховання проблем
Пісьмо чаго-то подабнага ўскладненае:
const user = apiResponse as User;
Асэрцыя не пераканальвае нічога ў чынным адпаведзе API — яна проста кажа компілятору пакліквацца вашымі словамі.
Адносаванне TypeScript да іншага часу выканання
TypeScript не выкананыя браузерам безпосередна. Ён спачатку кампілюецца у звычны JavaScript, перш чым запускаецца.
Это значыць, што всё, што вы вялікі час знаеце пра JavaScript, застаецца актуальным.
Практычны прыклад
Разглядзім просты кошачок для пакупак, напісаны так, як вы зазвычай ствараеце ў JavaScript, але тут даданы типы TypeScript.
interface CartItem {
id: number;
name: string;
price: number;
quantity: number;
}
function calculateCartTotal(
items: CartItem[]
): number {
return items.reduce((total, item) => {
return total + item.price * item.quantity;
}, 0);
}
const cart: CartItem[] = [
{
id: 1,
name: "Keyboard",
price: 2500,
quantity: 1
},
{
id: 2,
name: "Mouse",
price: 1200,
quantity: 2
}
];
const total = calculateCartTotal(cart);
console.log(`Cart total: ₹${total}`);
За такіх умов функцыя тепер захіщаная ад некоректных данных у кошачку.
Напрыклад, следуючы фрагмент не будзе кампілювацца:
const invalidCart: CartItem[] = [
{
id: 1,
name: "Keyboard",
price: "2500",
quantity: 1
}
];
Проблема заключаецца у тым, што price заданы як строка, хоць яго трэба было задаць як число.
Чы трэба кожнам проекту на JavaScript викорыстоўваць TypeScript?
Не завжды.
Звычны JavaScript таксама добра падходзіць для такіх ситуацый:
- Маленькія експерыменты
- Простыя скрыпты
- Швыдкія протатыпы
- Базовыя стартовыя сторункі
TypeScript частае ўсвойчыцца больш эфектываў у такіх ситуацыях:
- Большыя фронтэнд-застосункі
- Базы коду React і Next.js
- Сервісы бэкенду на Node.js
- Базы коду, якія дзеляцца между камандамі
- Продукты з довгай трымкай
- Праекты, якія працуюць з складнымі структурамі дадзеных
- Застосункі, якія ствараюць і падтрымліваюць калькі разработчыкаў
У загальных рысах, чым большы і давялей трымаецца проект, тым большую практычную корысть вы атрымаеце, адышоўшыся да TypeScript.
Заключныя меркі
TypeScript не ёсць заменай JavaScript — яны паўнэйша падымаюць кантракты напісання JavaScript, адколі абгортаюць ваш код у дапаможны шар безпекі.
Як чалавек, які ведае JavaScript, вы вялікая частка неабходных знанняў вясце ўжо:
- Зменны
- Функцыі
- Об’екты
- Масівы
- Класы
- Практыкі
- Модулі
- Асынхронны код
Гэта, што застаецца выучыць, — галоўная мерка як выражыць структуру вашых дадзенняў.
Хорашы пачатковы пункт включае:
- Прімітывныя типы
- Тыпы параметраў і рэзультатаў для функцый
- Інтерфейсы
- Тыпы аб’еднання
- Необавязковыя атрыбуты
- Генерікі
- Тыпаваныя адказы з API
Не намагайцеся адразу запам’ятаваць усі прыглыбленыя функцыі. Пачніце з анотавання звычайнага JavaScript і дазвольце патрэбам вашых рэальных проектаў кераваць тым, што вы выучыце далей.
Колі TypeScript стане частым аспектам вашай працы, вярнуцца да звычайнага, нетыпаванага JavaScript можа стаць неспадзевана небяпечным.