Generic класс
Generic-г зөвхөн функцэд биш, классуудад мөн ашиглаж болно. Generic класс нь нэг удаа бичсэн боловч тоо, мөр, объект — дурын төрлийн өгөгдлийг зохицуулдаг уян хатан бүтэц юм.
Анхны жишээ: Stack
Stack бол сүүлд оруулсан зүйлийг эхэлж гаргадаг (LIFO — Last In, First Out) өгөгдлийн бүтэц. Generic ашиглан бичвэл нэг классаар тоо, мөр, дурын төрлийг хадгалж болно:
class Stack<T> {
private утгууд: T[] = [];
нэмэх(утга: T): void {
this.утгууд.push(утга);
}
гаргах(): T | undefined {
return this.утгууд.pop();
}
харах(): T | undefined {
return this.утгууд[this.утгууд.length - 1];
}
хоосон_эсэх(): boolean {
return this.утгууд.length === 0;
}
get нийт(): number {
return this.утгууд.length;
}
}
// Тооны stack
const тооны_stack = new Stack<number>();
тооны_stack.нэмэх(1);
тооны_stack.нэмэх(2);
тооны_stack.нэмэх(3);
console.log(тооны_stack.гаргах()); // 3
console.log(тооны_stack.нийт); // 2
// Мөрийн stack
const мөрийн_stack = new Stack<string>();
мөрийн_stack.нэмэх("Монгол");
мөрийн_stack.нэмэх("TypeScript");
console.log(мөрийн_stack.харах()); // "TypeScript"
Жишээ: Queue
Queue бол эхэлж оруулсан зүйлийг эхэлж гаргадаг (FIFO — First In, First Out) бүтэц:
class Queue<T> {
private утгууд: T[] = [];
орох(утга: T): void {
this.утгууд.push(утга);
}
гарах(): T | undefined {
return this.утгууд.shift();
}
харах(): T | undefined {
return this.утгууд[0];
}
get нийт(): number {
return this.утгууд.length;
}
бүгдийг_харах(): T[] {
return [...this.утгууд];
}
}
interface Даалгавар {
id: number;
нэр: string;
}
const дарааллаа = new Queue<Даалгавар>();
дарааллаа.орох({ id: 1, нэр: "Имэйл илгээх" });
дарааллаа.орох({ id: 2, нэр: "Мэдэгдэл явуулах" });
дарааллаа.орох({ id: 3, нэр: "Тайлан бэлдэх" });
console.log(дарааллаа.гарах()); // { id: 1, нэр: "Имэйл илгээх" }
console.log(дарааллаа.нийт); // 2
extends ашиглах generic класс
Классын T-д мөн хязгаарлалт тавих боломжтой:
interface Танигдах {
id: number;
}
// T нь заавал id: number property-тэй байх ёстой
class Сан<T extends Танигдах> {
private утгууд: Map<number, T> = new Map();
нэмэх(утга: T): void {
this.утгууд.set(утга.id, утга);
}
олох(id: number): T | undefined {
return this.утгууд.get(id);
}
устгах(id: number): boolean {
return this.утгууд.delete(id);
}
бүгдийг_авах(): T[] {
return Array.from(this.утгууд.values());
}
}
interface Хэрэглэгч extends Танигдах {
нэр: string;
имэйл: string;
}
const хэрэглэгчийн_сан = new Сан<Хэрэглэгч>();
хэрэглэгчийн_сан.нэмэх({ id: 1, нэр: "Болд", имэйл: "bold@mail.com" });
хэрэглэгчийн_сан.нэмэх({ id: 2, нэр: "Бат", имэйл: "bat@mail.com" });
console.log(хэрэглэгчийн_сан.олох(1)); // { id: 1, нэр: "Болд", ... }
console.log(хэрэглэгчийн_сан.бүгдийг_авах().length); // 2
Generic класс өвлөх
Generic классыг extends ашиглан өвлүүлж болно:
class Үндсэн_жагсаалт<T> {
protected утгууд: T[] = [];
нэмэх(утга: T): void {
this.утгууд.push(утга);
}
get нийт(): number {
return this.утгууд.length;
}
}
// Generic-г тодорхой төрлөөр тогтоох
class Тооны_жагсаалт extends Үндсэн_жагсаалт<number> {
нийлбэр(): number {
return this.утгууд.reduce((н, т) => н + т, 0);
}
дундаж(): number {
return this.нийт > 0 ? this.нийлбэр() / this.нийт : 0;
}
}
const жагсаалт = new Тооны_жагсаалт();
жагсаалт.нэмэх(10);
жагсаалт.нэмэх(20);
жагсаалт.нэмэх(30);
console.log(жагсаалт.нийлбэр()); // 60
console.log(жагсаалт.дундаж()); // 20
Generic класс нь өгөгдлийн бүтэц (Stack, Queue, Map, Set), API хариу зохицуулагч, кэш систем зэрэг олон тохиолдолд хэрэглэгддэг. Нэг удаа сайн бичсэн generic класс бүхэл бүтэн төсөл даяар ашиглагдана.
Дараагийн хичээлд:
Utility Types — TypeScript-д суурилсан Partial, Required, Pick, Omit зэрэг бэлэн хэрэглүүрүүдийг сурна.