Примеры решений в TypeScript

Приветствую! Здесь вы наверняка найдете, что ищете. Примеры в лаборатории рассчитаны на то, что мы разбираем что-то конкретное.

Текущая статья посвящена клиент, zod, ограничение параллелизма и качество типов..

Поэтому за теорией по текущей теме вам — в энциклопедию. Если ещё не погружались, то маршрут прост:

  1. Основы
  2. Система и сеть
  3. Данные и разметка
  4. Код и разработка
  5. Языки
  6. Искусственный интеллект
  7. Проект
  8. Инфраструктура и безопасность
  9. Спин-офф

Обязательно пройдитесь.

А теперь приступим к нашему предмету.

Теория и соседние материалы

Термины

Термин Назначение
Type guard Сужение unknown до конкретного типа
Generics Параметризация типов (T)
strict Строгий режим компилятора
Runtime validation Проверка данных извне (zod, io-ts)

1. Type guard

type User = { id: string; email: string };

function isUser(x: unknown): x is User {
  if (typeof x !== 'object' || x === null) return false;
  const o = x as Record<string, unknown>;
  return typeof o.id === 'string' && typeof o.email === 'string';
}

function handlePayload(data: unknown) {
  if (!isUser(data)) throw new Error('Invalid user payload');
  console.log(data.email);
}

2. Утилитарные типы

type PartialUser = Partial<User>;
type UserEmail = Pick<User, 'email'>;
type ReadonlyUser = Readonly<User>;

3. Типизированный API-клиент

async function getJson<T>(url: string, init?: RequestInit): Promise<T> {
  const res = await fetch(url, init);
  if (!res.ok) throw new Error(`HTTP ${res.status}`);
  return (await res.json()) as T;
}

type Post = { id: number; title: string };
const post = await getJson<Post>('https://api.example.com/posts/1');

4. Ограничение параллелизма


5. Runtime-валидация (zod)


import { z } from 'zod';

const UserSchema = z.object({
  id: z.stringuuid
  email: z.stringemail
});

type User = z.infer<typeof UserSchema>;

const user = UserSchema.parse(jsonFromApi);

6. Discriminated union

type Result<T> =
  | { ok: true; value: T }
  | { ok: false; error: string };

function unwrap<T>(r: Result<T>): T {
  if (!r.ok) throw new Error(r.error);
  return r.value;
}

Типичные ошибки

  • as any вместо guard или zod.
  • Типы API не синхронизированы с OpenAPI.
  • strict: false в новых проектах.

Чек-лист

  • strict включён в tsconfig.
  • Внешний ввод проверяется на runtime.
  • Публичные функции экспортируют явные типы.