strictrejiminin hansı yoxlamaları açdığını izah etməkas constilə qiymətlərdən dəqiq literal tiplər almaqsatisfies-i tip annotasiyası vəasilə müqayisə etmək@typespaketlərindən istifadə etmək və sadə.d.tsfaylı yazmaq
Artıq tipləri, funksiyaları, interfeysləri, birləşmələri, sinifləri və generikləri bilirsən. Bu son dərs peşəkarların hər gün istifadə etdiyi dörd alət haqqındadır: səhvlərin çoxunu tutan ciddi rejim, qiymətlərdən dəqiq tip almaq üçün as const, tipi «genişləndirmədən» yoxlayan satisfies və tipi olmayan JavaScript kitabxanalarını TypeScript-ə tanıdan elan faylları.
Ciddi rejim
tsconfig.json-da "strict": true bir parametr deyil, bütöv bir yoxlamalar dəstidir. Onsuz TypeScript çox şeyə göz yumur və JavaScript-in ən tez-tez rast gəlinən səhvləri keçib gedir. Dəstin ən vacib üzvləri bunlardır:
strictNullChecks—nullvəundefinedayrıca tiplərdir; «ola bilsinundefined» olan qiyməti yoxlamadan istifadə etmək olmaz.noImplicitAny— tipi müəyyən edilə bilməyən parametr səssizcəanyolmur, xəta verilir.strictPropertyInitialization— sinfin hər sahəsi elanda və ya konstruktorda qiymət almalıdır.useUnknownInCatchVariables—catch (error)blokundaerrordəyişənianyyox,unknowntipli olur.
const users = [
{ name: 'Aysel', age: 15 },
{ name: 'Murad', age: 17 },
];
const found = users.find((u) => u.name === 'Leyla');
console.log(found.age);users.ts:7:13 - error TS18048: 'found' is possibly 'undefined'.
7 console.log(found.age);
~~~~~find heç nə tapmaya bilər. Ciddi rejim olmasa, kod səhvsiz kompilyasiya olunar və icra zamanı TypeError: Cannot read properties of undefined (reading 'age') ilə çökərdi.const users = [
{ name: 'Aysel', age: 15 },
{ name: 'Murad', age: 17 },
];
const found = users.find((u) => u.name === 'Leyla');
console.log(found?.age ?? 'not found');not found
?. və ?? ilə «tapılmadı» halını işləmək.as const
as const qiyməti «donmuş» kimi qəbul etməyi xahiş edir: sətirlər string yox, dəqiq literal tiplər olur, massiv yalnız oxunan kortejə, obyektin xassələri isə readonly xassələrə çevrilir. Bu, rollar, statuslar və parametrlər kimi sabit siyahılar üçün idealdır və keçən dərsdə danışdığımız enum-u rahatca əvəz edir:
const ROLES = ['admin', 'editor', 'viewer'] as const;
type Role = (typeof ROLES)[number];
function canEdit(role: Role): boolean {
return role !== 'viewer';
}
const Status = { Active: 'active', Blocked: 'blocked' } as const;
type Status = (typeof Status)[keyof typeof Status];
const s: Status = Status.Blocked;
console.log(ROLES.join(', '), canEdit('editor'), s);admin, editor, viewer true blocked
Role tipi 'admin' | 'editor' | 'viewer', Status tipi isə 'active' | 'blocked'-dır. Siyahı proqramda da mövcuddur — onu çap etmək və dövrə salmaq olar.const ROLES = ['admin', 'editor', 'viewer'] as const;
ROLES.push('guest');roles.ts:2:7 - error TS2339: Property 'push' does not exist on type 'readonly ["admin", "editor", "viewer"]'.
2 ROLES.push('guest');
~~~~as const massivi yalnız oxunan kortejə çevirir, ona görə push metodu yoxdur.satisfies operatoru
Tip annotasiyası (const x: T = ...) qiyməti yoxlayır, amma dəyişənin tipini T-yə genişləndirir və qiymət haqqında dəqiq məlumat itir. satisfies T isə yalnız yoxlayır: qiymət T-yə uyğun olmalıdır, dəyişən isə TypeScript-in çıxardığı dəqiq tipi saxlayır. Rənglər palitrasında bəzi rənglər sətir, bəziləri isə üç ədəddən ibarət kortejdir:
type ColorName = 'red' | 'green' | 'blue';
type Color = string | [number, number, number];
const palette = {
red: [255, 0, 0],
green: '#00ff00',
blue: [0, 0, 255],
} satisfies Record<ColorName, Color>;
console.log(palette.green.toUpperCase());
console.log(palette.red[0]);#00FF00 255
green-in sətir, red-in isə kortej olduğunu bilir, çünki satisfies dəqiq tipi saxlayır.type ColorName = 'red' | 'green' | 'blue';
type Color = string | [number, number, number];
const annotated: Record<ColorName, Color> = {
red: [255, 0, 0],
green: '#00ff00',
blue: [0, 0, 255],
};
annotated.green.toUpperCase();
const checked = {
red: [255, 0, 0],
green: '#00ff00',
bleu: [0, 0, 255],
} satisfies Record<ColorName, Color>;palette.ts:9:17 - error TS2339: Property 'toUpperCase' does not exist on type 'Color'.
Property 'toUpperCase' does not exist on type '[number, number, number]'.
9 annotated.green.toUpperCase();
~~~~~~~~~~~
palette.ts:14:3 - error TS2353: Object literal may only specify known properties, and 'bleu' does not exist in type 'Record<ColorName, Color>'.
14 bleu: [0, 0, 255],
~~~~green sadəcə Color-dır. İkinci səhv: satisfies qiyməti yenə də yoxlayır və bleu hərf səhvini tutur.| Yazılış | Yoxlayır? | Dəyişənin tipi |
|---|---|---|
const x: T = value | bəli | T (genişlənir) |
const x = value satisfies T | bəli | qiymətin dəqiq tipi |
const x = value as T | demək olar ki, yox | T |
Elan faylları və üçüncü tərəf kitabxanaları
Yalnız tipləri saxlayan, heç bir icra olunan kodu olmayan fayl. O, JavaScript kodunun TypeScript üçün «təlimatıdır»: hansı funksiyalar var, hansı parametrləri qəbul edir və nə qaytarır.
npm paketlərinin tipləri üç yolla gəlir. Bir çox müasir paket öz .d.ts fayllarını özü ilə gətirir və heç nə etmək lazım deyil. Digərləri üçün icma tipləri ayrıca @types/... paketlərində dərc edir. Heç biri yoxdursa, elan faylını özün yazırsan.
npm install lodash
npm install --save-dev @types/lodashdependencies-ə, onun tipləri isə yalnız proqram hazırlanarkən lazım olduğu üçün devDependencies-ə düşür.Tutaq ki, layihədə tipləri olmayan köhnə old-slug kitabxanası var — o, mətni URL üçün qısa ada çevirir. Onu import edəndə TypeScript xəbərdarlıq edir ki, modulun tipləri tapılmadı:
src/index.ts:1:21 - error TS7016: Could not find a declaration file for module 'old-slug'. '/home/leyla/blog/node_modules/old-slug/index.js' implicitly has an 'any' type.
Try `npm i --save-dev @types/old-slug` if it exists or add a new declaration (.d.ts) file containing `declare module 'old-slug';`
1 import slugify from 'old-slug';
~~~~~~~~~~@types/old-slug paketi yoxdursa, types/old-slug.d.ts faylını yaradıb modulu declare module ilə təsvir edirik. declare sözü deyir ki, bu kod başqa yerdə artıq var, biz yalnız onun tipini bildiririk:
declare module 'old-slug' {
export default function slugify(text: string, separator?: string): string;
}types/old-slug.d.ts — gövdəsiz funksiya imzası, yalnız tiplər.import slugify from 'old-slug';
const title = 'Hello from Baku';
console.log(slugify(title));
console.log(slugify(title, '_'));hello-from-baku hello_from_baku
src/index.ts indi səhvsiz yoxlanılır, redaktor parametrləri təklif edir, slugify(42) çağırışı isə TS2345 xətası verəcək.Öz kitabxananı dərc edəndə .d.ts fayllarını əl ilə yazmaq lazım deyil. tsconfig.json-da "declaration": true parametri ilə tsc hər .js faylının yanında onun .d.ts faylını da yaradır:
export interface User {
name: string;
age: number;
}
export declare function greet(user: User): string;greet.ts-dən yaradılmış greet.d.ts: interfeys və funksiyanın imzası qalıb, gövdə isə greet.js-dədir.Əsas fikirlər
strict: truestrictNullChecks,noImplicitAnyvə digər yoxlamaları açır; onu həmişə aktiv saxla.asvə!səhv mesajını gizlədir, amma problemi həll etmir.as constqiyməti dəqiq literal və yalnız oxunan tiplərə çevirir;(typeof LIST)[number]siyahıdan birləşmə tipi çıxarır.satisfies TqiymətiT-yə görə yoxlayır, amma dəyişənin dəqiq tipini saxlayır..d.tsfaylları yalnız tiplərdən ibarətdir; tiplər paketin özündən,@types/...paketlərindən və yadeclare moduleilə yazdığın fayldan gəlir.
Özünü yoxla
10 sual. Hər düzgün cavab XP qazandırır.
tsconfig.json-da "strict": true nə edir?