TypeScript
TypeScript — JavaScript'ga static typing qo'shadi. Angular loyihalarida standart til; intervyuda tiplar, generics, utility types va tsconfig sozlamalari chuqur tekshiriladi.
Asosiy tiplar — string, number, boolean, any, unknown, never, void
Nima bu?
TypeScript primitive va maxsus tiplar bilan xavfsiz kod yozishga yordam beradi. `any` — tip tekshiruvini o'chiradi (qochish kerak). `unknown` — har qanday qiymat, lekin ishlatishdan oldin tekshirish shart. `never` — hech qachon qaytmaydigan funksiya (xato yoki cheksiz loop). `void` — return qiymati yo'q funksiya. Angular'da `@Input()` va service metodlarida bu tiplar keng ishlatiladi.Kod misoli
let username: string = 'admin';
let age: number = 25;
let isActive: boolean = true;
// any — tip xavfsizligini yo'qotadi
let data: any = fetchData();
data.foo.bar(); // kompilyatsiya o'tadi, runtime xato bo'lishi mumkin
// unknown — xavfsiz alternativa
let input: unknown = getUserInput();
if (typeof input === 'string') {
console.log(input.toUpperCase()); // endi string deb ma'lum
}
function throwError(msg: string): never {
throw new Error(msg);
}
function logMessage(msg: string): void {
console.log(msg);
// return yo'q yoki return; — void
}
Imtihonda
- `any` va `unknown` farqi nima? Qaysi biri afzal? - `never` tipi qayerda ishlatiladi? (exhaustive check misoli)Yodlash uchun
Noma'lum ma'lumot — `unknown`; tip tekshiruvini o'chirmaslik — `any` dan qoch.interface vs type — farqlari va qachon ishlatish
Nima bu?
`interface` va `type` ko'pincha bir xil vazifani bajaradi — ob'ekt shaklini belgilash. `interface` declaration merging qo'llab-quvvatlaydi (bir nomga qo'shib yozish mumkin). `type` union, intersection, mapped va conditional typelar uchun mosroq. Amaliyotda ob'ekt kontraktlari uchun `interface`, murakkab tip kombinatsiyalari uchun `type` tavsiya etiladi.Kod misoli
// interface — kengaytirish va merge
interface User {
id: number;
name: string;
}
interface User {
email: string; // declaration merging
}
interface Admin extends User {
role: 'admin';
}
// type — union va murakkab tiplar
type Status = 'pending' | 'active' | 'banned';
type ApiResponse<T> = { data: T; error: null } | { data: null; error: string };
type Point = { x: number; y: number };
type ID = string | number;
// interface implements (Angular service kontrakti)
interface Logger {
log(message: string): void;
}
class ConsoleLogger implements Logger {
log(message: string): void {
console.log(message);
}
}
Imtihonda
- `interface` va `type` qachon tanlanadi? - Declaration merging nima? Nima uchun Angular library'larda interface ko'p?Yodlash uchun
Ob'ekt kontrakti → `interface`; union/mapped/conditional → `type`.Union, Intersection, Literal types
Nima bu?
Union (`A | B`) — qiymat bir nechta tipdan biri bo'lishi mumkin. Intersection (`A & B`) — barcha tiplarning property'larini birlashtiradi. Literal type — aniq qiymat (`'admin'`, `42`, `true`). Ular birgalikda discriminated union pattern uchun asos bo'ladi — Angular'da action/state modellarda keng qo'llaniladi.Kod misoli
type Role = 'user' | 'admin' | 'guest'; // string literal union
function setRole(role: Role) {
console.log(role);
}
// setRole('superadmin'); // xato — faqat union a'zolari
type Timestamp = number & { readonly __brand: unique symbol }; // nominal type pattern
type Person = { name: string; age: number };
type Employee = { employeeId: string; department: string };
type Staff = Person & Employee; // ikkala to'plam property
const staff: Staff = {
name: 'Ali',
age: 30,
employeeId: 'E001',
department: 'IT',
};
// Discriminated union
type Result =
| { status: 'success'; data: User[] }
| { status: 'error'; message: string };
function handle(result: Result) {
if (result.status === 'success') {
console.log(result.data.length); // TS data borligini biladi
} else {
console.log(result.message);
}
}
Imtihonda
- Union va intersection farqi nima? - Discriminated union nima? Angular NgRx action'larida qanday ishlatiladi?Yodlash uchun
Union — yoki; Intersection — va; Literal — aniq qiymat.Generics — T, constraint (extends), Utility types
Nima bu?
Generics — funksiya, class yoki type'ga tip parametr berish imkonini beradi, `any` ishlatmasdan qayta foydalanish mumkin bo'ladi. `T extends SomeType` constraint — generic chegaralanadi. Utility types (`Partial`, `Pick`, `Omit`, `Record`, `ReturnType`) mavjud tiplardan yangi tip yaratadi. Angular HttpClient, FormControl va RxJS Observable generics bilan ishlaydi.any bilan farqi tez-tez adashtiriladi: any tip tekshiruvini butunlay o'chiradi, generic esa chaqiruv vaqtida aniq tipni saqlab qoladi — firstElement(['a']) natijasi string | undefined bo'ladi, any[] bo'lsa hamma narsa any bo'lib qoladi va keyingi zanjirda xatolar yashiriladi. Yana bir nuance: generic funksiyaga default tip berish mumkin (class ApiStore<T = unknown>), lekin default constraint'ni almashtirmaydi — T extends Identifiable = Identifiable kabi ikkalasini birga yozish kerak bo'lganda ko'p chalkashtiriladi.
Kod misoli
// Sodda generic
function firstElement<T>(arr: T[]): T | undefined {
return arr[0];
}
firstElement([1, 2, 3]); // number | undefined
firstElement(['a', 'b']); // string | undefined
// Constraint
interface Identifiable {
id: number;
}
function findById<T extends Identifiable>(items: T[], id: number): T | undefined {
return items.find((item) => item.id === id);
}
// Generic class
class ApiStore<T> {
private items: T[] = [];
add(item: T): void {
this.items.push(item);
}
getAll(): readonly T[] {
return this.items;
}
}
// Utility types
interface Product {
id: number;
name: string;
price: number;
description: string;
}
type ProductUpdate = Partial<Product>; // barcha optional
type ProductPreview = Pick<Product, 'id' | 'name' | 'price'>;
type ProductWithoutDesc = Omit<Product, 'description'>;
type ProductMap = Record<number, Product>;
type CreateProductFn = () => Product;
type ProductResult = ReturnType<CreateProductFn>; // Product
Imtihonda
- Generic nima uchun kerak? `any[]` o'rniga `T[]` afzalligi? - `Partial`, `Pick`, `Omit` farqlari va amaliy misol?Yodlash uchun
Qayta foydalanish + tip xavfsizligi → Generic; mavjud tipdan yangi → Utility type.Type Guards — typeof, instanceof, in, custom is
Nima bu?
Type guard — runtime tekshiruv orqali TypeScript'ga tipni toraytirish (narrowing). `typeof` primitive uchun, `instanceof` class instance uchun, `in` ob'ekt property mavjudligini tekshiradi. Custom type guard — `value is Type` qaytaruvchi funksiya; discriminated union bilan juda kuchli. Angular service'larda API javobini tekshirishda ishlatiladi.Kod misoli
function formatValue(value: string | number): string {
if (typeof value === 'number') {
return value.toFixed(2); // value: number
}
return value.toUpperCase(); // value: string
}
class Cat {
meow() { return 'miyov'; }
}
class Dog {
bark() { return 'hav'; }
}
function speak(pet: Cat | Dog) {
if (pet instanceof Cat) {
return pet.meow();
}
return pet.bark();
}
interface Bird { fly(): void; }
interface Fish { swim(): void; }
function move(creature: Bird | Fish) {
if ('fly' in creature) {
creature.fly();
} else {
creature.swim();
}
}
// Custom type guard
interface User {
id: number;
name: string;
}
function isUser(value: unknown): value is User {
return (
typeof value === 'object' &&
value !== null &&
'id' in value &&
'name' in value &&
typeof (value as User).id === 'number' &&
typeof (value as User).name === 'string'
);
}
function processInput(input: unknown) {
if (isUser(input)) {
console.log(input.name); // User deb ma'lum
}
}
Imtihonda
- Type narrowing nima? Qanday usullar bor? - Custom type guard (`is`) qanday yoziladi va nima uchun kerak?Yodlash uchun
Runtime tekshiruv → TypeScript tip torayadi; murakkab holat → `value is Type`.Conditional types — T extends U ? X : Y
Nima bu?
Conditional type — tip darajasida if/else: `T extends U ? X : Y`. Distributive conditional type union ustida ta'sir qiladi — har bir a'zo alohida tekshiriladi. `infer` kalit so'zi tipni "chiqarib olish" uchun ishlatiladi. Bu advanced utility typelar va library typing uchun asos — masalan, `ReturnType`, `Parameters` shunday yaratilgan.Gotcha: distributivity faqat generic yalang'och (naked) tip parametri union bo'lganda ishlaydi — T o'rniga [T] (tuple ichiga o'rash) yozilsa, distribution o'chadi va butun union bittalik sifatida tekshiriladi: type ToArrayNonDist<T> = [T] extends [any] ? T[] : never; — bu trik generic library kodida union'ni "bo'linmasin" deb ataylab qo'llaniladi. Bu farqni bilmaslik ko'pincha kutilmagan never yoki noto'g'ri union natijasiga olib keladi.
Kod misoli
type IsString<T> = T extends string ? true : false;
type A = IsString<string>; // true
type B = IsString<number>; // false
// Distributive — union bo'ylab tarqaladi
type ToArray<T> = T extends any ? T[] : never;
type C = ToArray<string | number>; // string[] | number[]
// infer — return tipini olish
type MyReturnType<T> = T extends (...args: any[]) => infer R ? R : never;
function getUser() {
return { id: 1, name: 'Ali' };
}
type UserReturn = MyReturnType<typeof getUser>;
// { id: number; name: string }
// Amaliy: null ni olib tashlash
type NonNullable<T> = T extends null | undefined ? never : T;
type Safe = NonNullable<string | null>; // string
Imtihonda
- Conditional type qanday ishlaydi? Distributive nima degani? - `infer` nima qiladi? `ReturnType` qanday ishlaydi?Yodlash uchun
Tip if/else: `T extends U ? X : Y`; tip chiqarish: `infer`.Mapped types — keyof, in, readonly, ?
Nima bu?
Mapped type — mavjud tip property'larini aylanib, yangi tip yaratadi: `{ [K in keyof T]: ... }`. `readonly` va `?` modifier'larni qo'shish yoki olib tashlash mumkin (`-readonly`, `-?`). `keyof` ob'ekt tipining kalitlar union'ini beradi. Bu `Partial`, `Required`, `Readonly` kabi utility typelarning asosi.Gotcha: readonly va ? faqat compile vaqtida tekshiriladi — runtime'da ob'ektni hali ham o'zgartirish mumkin (Object.freeze bo'lmasa), shuning uchun "readonly = immutable" deb ishonib qolish xato. as bilan key remapping (yuqoridagi Getters<T> misoli) TS 4.1+ xususiyati — undan oldingi versiyalarda faqat mavjud key'larni saqlash yoki olib tashlash (never bilan) mumkin edi, key nomini o'zgartirib bo'lmasdi.
Kod misoli
interface Todo {
title: string;
completed: boolean;
dueDate: Date;
}
// Barcha property optional
type PartialTodo = {
[K in keyof Todo]?: Todo[K];
};
// Barcha property readonly
type ReadonlyTodo = {
readonly [K in keyof Todo]: Todo[K];
};
// Modifier olib tashlash
type MutableTodo = {
-readonly [K in keyof ReadonlyTodo]: ReadonlyTodo[K];
};
// Property nomini o'zgartirish pattern
type Getters<T> = {
[K in keyof T as `get${Capitalize<string & K>}`]: () => T[K];
};
type TodoGetters = Getters<Todo>;
// { getTitle: () => string; getCompleted: () => boolean; getDueDate: () => Date }
// Faqat string property'lar
type StringKeys<T> = {
[K in keyof T as T[K] extends string ? K : never]: T[K];
};
type TodoStrings = StringKeys<Todo>; // { title: string }
Imtihonda
- Mapped type qanday yoziladi? `keyof` nima qaytaradi? - `Partial`T`` qanday implement qilinadi?Yodlash uchun
`{ [K in keyof T]: ... }` — har property uchun yangi tip.Template literal types
Nima bu?
Template literal type — string literal tiplarni `` `hello ${Name}` `` ko'rinishida birlashtirish. Union bilan birlashtirganda barcha kombinatsiyalar hosil bo'ladi. Event nomlari, CSS property, API route va permission string'larini tip darajasida modellashtirish uchun ishlatiladi. TypeScript 4.1+ xususiyati.Gotcha: ikkita union'ni birlashtirish (masalan, `${HttpMethod} ${UserRoutes}` — 4 usul × 3 route) kombinatorial portlash beradi — katta union'lar bilan bu compiler'ni sekinlashtirishi yoki TS2590: Expression produces a union type that is too complex xatosini keltirib chiqarishi mumkin. Shu sababli juda keng template literal'larni production kodda ehtiyotkorlik bilan ishlatish kerak.
Kod misoli
type EventName = 'click' | 'focus' | 'blur';
type HandlerName = `on${Capitalize<EventName>}`;
// 'onClick' | 'onFocus' | 'onBlur'
type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE';
type ApiRoute = `/api/${string}`;
type UserRoutes =
| '/api/users'
| '/api/users/:id'
| '/api/users/:id/posts';
type MethodRoute = `${HttpMethod} ${UserRoutes}`;
// 'GET /api/users' | 'POST /api/users' | ...
// CSS unit pattern
type CssValue = `${number}px` | `${number}rem` | `${number}%`;
function setWidth(value: CssValue) {
document.body.style.width = value;
}
setWidth('100px'); // OK
// setWidth('100'); // xato
// String manipulation utility'lar
type Join<K, V> = K extends string ? `${K}:${V & string}` : never;
type Pair = Join<'name', string>; // 'name:string'
Imtihonda
- Template literal type nima? Qanday amaliy foydasi bor? - `'on${Capitalize`T`}'` qanday ishlaydi?Yodlash uchun
String literal union + template = barcha string kombinatsiyalari tipda.Decorators — class, method, property decorator
Nima bu?
Decorator — class, method, property yoki parameterga metadata va xatti-harakat qo'shuvchi funksiya (`@Decorator`). Angular butunlay decorator'larga tayanadi: `@Component`, `@Injectable`, `@Input`. Decorator factory — parametrlar qabul qiluvchi funksiya qaytaradi. TypeScript 5+ Stage 3 decorator'lari standartlashtirilgan; Angular o'z metadata tizimini ishlatadi.Muhim nuance: Angular hali experimentalDecorators: true (legacy TC39 Stage 2, reflect-metadata ga tayangan) ishlatadi, standart TS 5 Stage 3 decorator'lar esa boshqa runtime semantikaga ega (masalan, emitDecoratorMetadata ishlamaydi, descriptor.value o'rniga class field initializer tartibi farqli). Ikkalasini aralashtirib ishlatib bo'lmaydi — loyihada qaysi rejim yoqilganini bilish (tsconfig.jsondagi experimentalDecorators) muhim, aks holda decorator kutilganidek ishlamaydi.
Kod misoli
// Method decorator — chaqiruvni log qilish
function Log(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
const original = descriptor.value;
descriptor.value = function (...args: unknown[]) {
console.log(`Chaqirildi: ${propertyKey}`, args);
return original.apply(this, args);
};
return descriptor;
}
// Property decorator factory
function Required(message: string) {
return function (target: object, propertyKey: string) {
let value: unknown;
Object.defineProperty(target, propertyKey, {
get: () => value,
set: (newVal) => {
if (newVal === undefined || newVal === null) {
throw new Error(message);
}
value = newVal;
},
});
};
}
class UserService {
@Required('name bo\'sh bo\'lmasin')
name!: string;
@Log
greet(name: string): string {
return `Salom, ${name}!`;
}
}
// Angular misoli (konseptual)
// @Component({ selector: 'app-user', template: '<p>{{ name }}</p>' })
// @Injectable({ providedIn: 'root' })
// @Input() userId!: number;
Imtihonda
- Decorator nima? Angular'da qaysi decorator'lar eng ko'p ishlatiladi? - Decorator factory va oddiy decorator farqi nima?Yodlash uchun
Decorator = `@Fn` — class/method/property'ga meta-xatti-harakat qo'shish.tsconfig — strict, noImplicitAny, strictNullChecks
Nima bu?
`tsconfig.json` TypeScript kompilyator sozlamalari. `strict: true` bir nechta qat'iy tekshiruvlarni yoqadi. `noImplicitAny` — tip berilmagan o'zgaruvchi uchun yashirin `any` taqiqlanadi. `strictNullChecks` — `null` va `undefined` alohida hisobga olinadi; eng ko'p xato oldini oladigan sozlama. Angular CLI yangi loyihalarda `strict` default yoqilgan.Muhim: strict: true yagona flag emas — u noImplicitAny, strictNullChecks, strictFunctionTypes, strictBindCallApply, strictPropertyInitialization, noImplicitThis, alwaysStrict kabi bir nechta sub-flag'ni birdaniga yoqadi. Mavjud katta loyihani strict rejimga o'tkazishda odatda bittalab yoqib, xatolarni bosqichma-bosqich tuzatish tavsiya etiladi — barchasini birdan yoqish yuzlab xatoni bir vaqtda chiqarishi mumkin. Shuningdek, strict: true build vaqtidagi tip xavfsizligini beradi, lekin runtime'da hech narsani kafolatlamaydi — masalan, JSON.parse yoki tashqi API javobi hali ham noto'g'ri shakl kelishi mumkin, shu uchun chegaralarda (API, forma) runtime validatsiya (masalan, Zod) kerak bo'ladi.
Kod misoli
{
"compilerOptions": {
"strict": true,
"noImplicitAny": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"target": "ES2022",
"module": "ES2022",
"moduleResolution": "bundler",
"experimentalDecorators": true,
"emitDecoratorMetadata": true
},
"angularCompilerOptions": {
"strictTemplates": true,
"strictInjectionParameters": true
}
}
// strictNullChecks yoqilganda:
let name: string = null; // xato — string | null kerak
let nameOrNull: string | null = null; // OK
function findUser(id: number): User | undefined {
return users.find((u) => u.id === id);
}
const user = findUser(1);
// console.log(user.name); // xato — user undefined bo'lishi mumkin
console.log(user?.name); // OK
// noImplicitAny:
function parse(data) { // xato — parametr tipi yo'q
return JSON.parse(data);
}
function parseSafe(data: string): unknown {
return JSON.parse(data);
}
Imtihonda
- `strict: true` nimalarni yoqadi? Angular loyihada nima uchun muhim? - `strictNullChecks` yoqilganda `@Input()` optional qanday belgilanadi?Yodlash uchun
Yangi loyiha — `strict: true`; null xavfi — `strictNullChecks`.