Ответ
Один из сложных аспектов — условные типы (Conditional Types). Они позволяют создавать типы, которые зависят от других типов. Например:
type IsString<T> = T extends string ? true : false;
type A = IsString<'hello'>; // true
type B = IsString<42>; // falseДругой пример — Mapped Types с модификаторами (readonly, ?):
type Partial<T> = {
[P in keyof T]?: T[P];
};
interface User {
name: string;
age: number;
}
type PartialUser = Partial<User>; // { name?: string; age?: number }Также сложны утилиты типа infer для вывода типов внутри условных типов:
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : never;
function foo() { return 42; }
type FooReturn = ReturnType<typeof foo>; // number