TypeScript-də Generics
-
Generics — TypeScript-də məlumatların tipini dinamik şəkildə müəyyən etmək üçün istifadə olunan bir vasitədir. Generics proqramlarımızı yenidən istifadə edilə bilən və tip təhlükəsizliyi təmin edən şəkildə yazmağımıza kömək edir.
Bu konsept bizə funksiyalarda, interfeyslərdə, classlarda və tiplərdə konkret tip əvəzinə gələcəkdə təyin ediləcək tip dəyişəni (
T
,U
,K
, s.) istifadə etməyə imkan verir.
Niyə Generics istifadə olunur?
Əgər bir funksiyanı müxtəlif tiplərlə işləyəcək şəkildə yazmaq istəyiriksə və həmçinin TypeScript-in tip yoxlamasından faydalanmaq istəyiriksə, Generics çox faydalıdır.
Sadə Generics nümunəsi
function identity<T>(value: T): T { return value; } const str = identity<string>("Hello"); const num = identity<number>(42);
Bu nümunədə
identity
funksiyası hər hansı tipdə (T
) dəyər alır və onu geri qaytarır. Bu funksiyanı həmstring
, həmnumber
, həm də başqa istənilən tiplərlə istifadə etmək olar.
Generics ilə Array işlənməsi
function getFirstElement<T>(arr: T[]): T { return arr[0]; } const first = getFirstElement<string>(["apple", "banana"]); const firstNum = getFirstElement<number>([10, 20, 30]);
Burada
T[]
generik array-dir. Hansı tipdə array versəniz, TypeScript həmin tipdə cavab qaytaracaq.
Generics ilə Interface və Type-lar
interface Box<T> { content: T; } const stringBox: Box<string> = { content: "salam" }; const numberBox: Box<number> = { content: 123 };
Burada
Box<T>
interfeysi istənilən tipdə məlumat saxlamaq üçün generik olaraq təyin olunub.
Generics ilə Class
class Container<T> { private value: T; constructor(val: T) { this.value = val; } getValue(): T { return this.value; } } const container = new Container<string>("Data"); console.log(container.getValue()); // "Data"
Bu nümunədə
Container
class-ı generikdir və istənilən tipdə məlumat saxlaya bilir.
Bir neçə tip dəyişəni ilə Generics
function merge<T, U>(obj1: T, obj2: U): T & U { return { ...obj1, ...obj2 }; } const merged = merge({ name: "Ali" }, { age: 25 }); // merged: { name: "Ali", age: 25 }
merge
funksiyası iki fərqli tip qəbul edir və onların birləşməsini qaytarır.
Tip məhdudiyyətləri (Constraints)
Bəzən generik tipin müəyyən xüsusiyyətləri olmasını istəyə bilərik. Bu zaman
extends
istifadə olunur:function logLength<T extends { length: number }>(value: T): void { console.log(value.length); } logLength("Salam"); // 5 logLength([1, 2, 3]); // 3
Bu nümunədə
T
tipi yalnızlength
xüsusiyyətinə sahib olan tiplərlə məhdudlaşdırılıb.
keyof
Operatorukeyof
operatoru bir obyektin açarlarını (key
) tip kimi əldə etməyə imkan verir.interface Person { name: string; age: number; } type PersonKeys = keyof Person; // "name" | "age"
Bu, xüsusilə dinamik açarlarla işləyərkən faydalıdır:
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] { return obj[key]; } const person = { name: "Ali", age: 30 }; const name = getProperty(person, "name"); // "Ali"
infer
və Conditional TypesConditional types tip əsaslı şərti ifadələr yaratmağa imkan verir.
infer
isə bu şərtlər daxilində tip çıxarmağa (inference) kömək edir.infer
ilə tip çıxarmatype ReturnType<T> = T extends (...args: any[]) => infer R ? R : any; type Num = ReturnType<() => number>; // number type Str = ReturnType<(x: string) => string>; // string
Burada
infer R
funksiyanın dönüş tipini çıxarır.Flatten
nümunəsitype Flatten<T> = T extends Array<infer U> ? U : T; type Str = Flatten<string[]>; // string type Num = Flatten<number>; // number
Əgər
T
array tipidirsə, onun element tipini çıxarır, əks haldaT
-ni olduğu kimi saxlayır.
Default Generic parametrlər
Generik parametrlər üçün default (susmaya görə) dəyərlər təyin etmək mümkündür:
function createArray<T = number>(length: number, value: T): T[] { return new Array(length).fill(value); } const numberArray = createArray(3, 0); // [0, 0, 0] const stringArray = createArray<string>(3, "hello"); // ["hello", "hello", "hello"]
Burada
T
üçün default olaraqnumber
tipi təyin edilib.
Generics-in Üstünlükləri
Üstünlük İzah Yenidən istifadə
Eyni funksiya və ya sinif müxtəlif tiplərlə işləyə bilir. Tip təhlükəsizliyi
Giriş və çıxış tipləri dəqiq müəyyənləşir. Daha az təkrar kod
Eyni əməliyyatı fərqli tiplərlə etmək üçün ayrıca funksiyalara ehtiyac yoxdur.
Nəticə
Generics TypeScript-də çox güclü bir vasitədir və proqramların daha elastik, tip təhlükəsiz və yenidən istifadə oluna bilən olmasını təmin edir.
Əgər siz funksiyalarınızın və strukturlarınızın tiplərini gələcəkdə təyin etmək istəyirsinizsə və təkrarı azaltmaq istəyirsinizsə — Generics istifadə etməyiniz tövsiyə olunur.
-
Mapped Types — TypeScript-in qabaqcıl xüsusiyyətlərindən biridir və mövcud obyektlərin açarlarını (yəni
keyof
) istifadə edərək yeni tip yarada bilməyə imkan verir. Bu xüsusiyyət əsasən reusable və dinamik tiplər yaratmaq üçün istifadə olunur.
1. Əsas sintaksis və istifadə
Mapped Type yaratmaq üçün aşağıdakı sintaksisdən istifadə olunur:
type MyMappedType<T> = { [P in keyof T]: T[P]; };
Bu o deməkdir ki,
T
tipində olan obyektin hər bir açarı (P
) üçün həmin açarın tipi saxlanılır.Məsələn:
type User = { name: string; age: number; }; type ReadonlyUser = { readonly [P in keyof User]: User[P]; }; // nəticə: // { // readonly name: string; // readonly age: number; // }
2. Sadə misallar
a) Readonly
type Readonly<T> = { readonly [K in keyof T]: T[K]; };
b) Partial
type Partial<T> = { [K in keyof T]?: T[K]; };
c) Required
type Required<T> = { [K in keyof T]-?: T[K]; };
3.
as
ilə Key Rename (Advanced Feature)type RemoveUnderscore<T> = { [K in keyof T as K extends `_${infer R}` ? R : K]: T[K]; }; type User = { _id: string; name: string; }; type CleanUser = RemoveUnderscore<User>; // Nəticə: // { // id: string; // name: string; // }
Burada
as
operatoru ilə_${infer R}
pattern-i ilə başlayan açarlarıR
şəklində dəyişmişik.
4.
Record
Mapped Type kimitype Record<K extends keyof any, T> = { [P in K]: T; }; const roles: Record<"admin" | "user", boolean> = { admin: true, user: false, };
5. Real həyatdan misal
Form input-lar üçün model yaradın:
type FormFields = { email: string; password: string; }; type FormErrors = { [K in keyof FormFields]?: string; };
Bu halda
FormErrors
tipindəemail
vəpassword
sahələri olacaq, amma optional və dəyərləristring
olacaq.
Bilik paylaşdıqca artan bir sərvətdir