Почему ваши типы TypeScript могут быть не так безопасны, как кажется
Вы освоили интерфейсы и расширяете их через extends и implements. Редактор показывает меньше красных подчеркиваний, чем когда-либо прежде. Тем не менее ошибки времени выполнения все равно проникают в код. Обещанная безопасность типов при компиляции кажется неполной.
Условные типы: логика в системе типов
Условные типы добавляют логику в систему типов TypeScript. Они позволяют выражать условия типа «если этот тип соответствует условию, то использовать один тип, иначе другой». Например:
type IsString<T> = T extends string ? true : false;
type Test1 = IsString<'hello'>; // true
type Test2 = IsString<42>; // false
Но настоящая мощь условных типов раскрывается при использовании ключевого слова infer, которое позволяет извлекать части типов и работать с ними:
type ExtractReturnType<T> = T extends (...args: any[]) => infer R ? R : never;
function getUser() {
return { id: 1, name: 'Alice' };
}
type User = ExtractReturnType<typeof getUser>; // User = { id: number, name: string }
Этот подход настолько полезен, что стандартная библиотека TypeScript включает его как ReturnType<T>.
Типы шаблонных строк: манипуляции со строками на уровне типов
Введенные в TypeScript 4.1, типы шаблонных строк позволяют манипулировать строковыми шаблонами прямо в системе типов. Это полезно для работы с маршрутами API или библиотеками CSS-in-JS, где важны паттерны строковых значений:
type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE';
type ApiVersion = 'v1' | 'v2';
type ApiEndpoint = `${HttpMethod} /api/${ApiVersion}/${string}`;
const valid: ApiEndpoint = 'GET /api/v1/users';