TypeScript zaawansowany
Generics, conditional types, mapped types, template literal types, Stage 3 decorators i nowości TypeScript 5.x.
6 zaawansowanych funkcji TypeScript
Generics, conditional types, mapped types, template literals, decorators i type guards — każda funkcja otwiera nowe możliwości type-safe kodu.
Generics
Parametryzacja typów
function identity(arg: T): T
Reusable, type-safe collections i utilities
Conditional Types
Logika typów
T extends U ? X : Y
Utility types, type transformations
Mapped Types
Transformacja typów
{[K in keyof T]: T[K]}
Partial, Required, Readonly, custom transforms
Template Literal Types
String types
type EventName = 'on${Capitalize}'
API routes, event names, CSS properties
Decorators (Stage 3)
Metadata / AOP
@Controller('users')
NestJS, Angular, TypeORM, class-validator
Type Guards + infer
Narrowing / Inference
value is string, infer R
Runtime safety, conditional type inference
Często zadawane pytania
Generics w TypeScript — co to jest i jak używać?
Generics: parametryzowane typy — jak szablony (templates) w C++ lub Java. Pozwalają pisać kod wielokrotnego użytku z zachowaniem type safety. Podstawowy generic: function identity(arg: T): T {return arg}. identity('hello') — TypeScript infers T = string. identity(42) — T = number. Generic z constraints: function getLength(arg: T): number. T extends {length: number} — T musi mieć property length. String, Array, itd. spełniają. Generic interface: interface Repository {findById(id: string): Promise. findAll(): Promise. create(entity: T): Promise}. Generic class: class Stack {private items: T[] = []. push(item: T): void. pop(): T | undefined}. Multiple generics: function merge(a: T, b: U): T & U. Conditional types z generics: type NonNullable = T extends null | undefined ? never : T. Mapped types: type Partial = {[P in keyof T]?: T[P]}. Required, Readonly, Pick, Omit. Utility types wbudowane: Partial, Required, Readonly, Record, Pick, Omit, Exclude, Extract, NonNullable, ReturnType, Parameters, InstanceType, Awaited. infer keyword: type ReturnType = T extends (...args: any) => infer R ? R : never. Variadic tuple types: type Concat = [...A, ...B]. Template literal types: type EventName = 'on${Capitalize}'. Distributive conditional types: T extends U — działa per union member.
Conditional types, mapped types i advanced utility types?
Conditional types: T extends U ? X : Y. Podstawowe: type IsString = T extends string ? true : false. Nested: type DeepReadonly = T extends object ? {readonly [K in keyof T]: DeepReadonly} : T. Distributive: type ToArray = T extends any ? T[] : never. ToArray = string[] | number[] (nie (string|number)[]). infer w conditional types: type UnwrapPromise = T extends Promise ? U : T. type FirstParam = T extends (first: infer F, ...rest: any[]) => any ? F : never. Mapped types: {[K in keyof T]: ...} — iteruj po kluczach. Optional: {[K in keyof T]?: T[K]}. Readonly: {readonly [K in keyof T]: T[K]}. Remapping z as: {[K in keyof T as K extends string ? Capitalize : K]: T[K]}. Filtered mapped: {[K in keyof T as T[K] extends string ? K : never]: T[K]}. Template literal types: type EventName = 'on${Capitalize}'. type CSSProperty = 'padding-${string}'. type i18nKeys = 'en' | 'pl'. type Translation = {[K in i18nKeys]: string}. Discriminated unions: type Shape = {kind: 'circle', radius: number} | {kind: 'rect', w: number, h: number}. Exhaustive check: default: const _: never = shape. TypeScript strict mode opcje: strictNullChecks (najważniejszy). noImplicitAny. strictFunctionTypes. strictPropertyInitialization. noImplicitReturns. exactOptionalPropertyTypes (v4.4). useUnknownInCatchVariables.
Decorators w TypeScript — co to jest i kiedy używać?
Decorators: metadata annotations dla klas, metod, właściwości i parametrów. Stage 3 TC39 (native JS decorators — TypeScript 5.0+). Legacy decorators: experimentalDecorators: true (Reflect.metadata). Używane przez: NestJS (wszystkie dekoratory). TypeORM / MikroORM (@Entity, @Column). class-transformer (@Type, @Expose). class-validator (@IsEmail, @MinLength). Angular (cały framework). Class decorator: @sealed function sealed(constructor: Function) {Object.seal(constructor). Object.seal(constructor.prototype)}. Method decorator: @deprecated (loguje deprecation warning). Property decorator: @observable — integrates z MobX. Parameter decorator: @Inject(TOKEN) — dependency injection. NestJS przykład: @Controller('users') — route prefix. @Get(':id') — HTTP method + path. @Injectable() — DI provider. @Module({imports, providers, controllers}) — module definition. class-validator + class-transformer: @IsEmail() email: string. @MinLength(8) password: string. validate(dto) — walidacja. plainToClass(CreateUserDto, body) — transform + validate. TypeScript 5.x nowe dekoratory (TC39 Stage 3): bez Reflect.metadata. context zamiast descriptor. Kompatybilne ze standardem JS. NestJS 10+ wspiera nowe dekoratory. Kiedy unikaj dekoratorów: prostsze projekty (overhead konfiguracji). Bun + Elysia (własny system). Bez NestJS/Angular — useReducer może być prostszy.
Type guards, assertion functions i narrowing?
Type narrowing: TypeScript zawęża typ na podstawie kontroli. typeof: if (typeof value === 'string') — TypeScript wie że value: string w bloku. instanceof: if (error instanceof CustomError) — value: CustomError. in operator: if ('email' in user) — user ma property email. Type guards (user-defined): function isString(value: unknown): value is string {return typeof value === 'string'}. isString(x) — po true, x jest typed jako string. Discriminated union narrowing: switch (shape.kind) {case 'circle': ...} — TypeScript wie jaki typ. Assertion functions: function assertIsString(value: unknown): asserts value is string {if (typeof value !== 'string') throw new Error(...)}. assertIsString(x) — po wywołaniu x jest string. never type: wyczerpujące sprawdzenie. default: const _: never = value — błąd jeśli nie wszystkie przypadki obsłużone. unknown vs any: unknown — bezpieczniejszy any. Musisz sprawdzić typ przed użyciem. any — wyłącza type checking. Unikaj any, używaj unknown. Satisfies operator (TS 4.9): const config = {...} satisfies Config. Walidacja bez zmiany inferowanego typu. as const: const colors = ['red', 'blue'] as const. Typ: readonly ['red', 'blue']. Literalne typy zamiast string[]. Template literal zamiast string enum. noUncheckedIndexedAccess: array[index] jest T | undefined (nie T). Bezpieczniejsze array access.
TypeScript 5.x — co nowego i jak migrować z starszych wersji?
TypeScript 5.0 (2023): Decorators Stage 3 (TC39). const type parameters. All enums jako union enums. --moduleResolution bundler. speedup (15-20%). TypeScript 5.1: Unrelated types for getters/setters. Undefined-returning functions. JSX transform. TypeScript 5.2: using declarations (Stage 3 Explicit Resource Management). Symbol.dispose, Symbol.asyncDispose. Automatyczne cleanup zasobów (connection, file, etc). TypeScript 5.3: Import attributes (JSON modules). Resolution customization flags. TypeScript 5.4: NoInfer utility type. Preserved narrowing in closures. TypeScript 5.5: Inferred type predicates (automatyczne type guards!). Regular Expression type checking. TypeScript 5.6: Iterator methods (filter, map, take na lazy sequences). Disallowed nullish and truthy checks. TypeScript 5.7: Path rewriting (node16 moduleResolution). Checks for never-initialized variables. Migracja: strict mode włącz stopniowo. tsconfig.json: 'strict': true. Napraw błędy jeden po drugim. ts-migrate — automatyczna migracja. allowJs: true + checkJs: false dla mixed projektu. skipLibCheck: true — pomiń sprawdzanie d.ts. Narzędzia TypeScript: ts-morph (TypeScript Compiler API). tsc --noEmit (tylko type check). ts-prune (nieużywane exports). knip (dead code). type-coverage (procent pokrycia typami).
Powiązane artykuły
Skontaktuj się z nami
Porozmawiajmy o Twoim projekcie. Bezpłatna wycena w ciągu 24 godzin.
Wyślij zapytanie
Telefon
+48 790 814 814
Pon-Pt: 9:00 - 18:00
adam@fotz.pl
Odpowiadamy w ciągu 24h
Adres
Plac Wolności 16
61-739 Poznań
Godziny pracy
Wolisz porozmawiać?
Zadzwoń teraz i porozmawiaj z naszym specjalistą o Twoim projekcie.
Zadzwoń teraz