← Назад к вопросам

Для чего можно использовать тип?

1.7 Middle🔥 181 комментариев
#JavaScript Core

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Для чего можно использовать type в TypeScript?

Type в TypeScript - это одна из основных конструкций для описания формы данных. Это мощный инструмент, который помогает ловить ошибки ещё во время разработки, до запуска кода. Есть два похожих способа: type и interface. Разберёмся, для чего они нужны и в чём разница.

Основное использование: описание формы данных

type используется для описания структуры объектов, функций, примитивов и всего остального:

// Описание объекта пользователя
type User = {
  id: number;
  name: string;
  email: string;
  age?: number; // Необязательное поле
};

// Использование
const user: User = {
  id: 1,
  name: "Alice",
  email: "alice@example.com",
  age: 30
};

1. Типы для функций

type описывает параметры и возвращаемое значение функции:

// Тип функции
type Callback = (data: string, error: Error | null) => void;

// Использование
const handleResponse: Callback = (data, error) => {
  if (error) {
    console.error(error);
  } else {
    console.log(data);
  }
};

// Функция с параметром типа Callback
function fetchData(callback: Callback) {
  // ...
}

2. Союзные типы (Union Types)

type позволяет описать несколько возможных типов:

// Переменная может быть либо строкой, либо числом
type ID = string | number;

const userId: ID = "user-123"; // OK
const adminId: ID = 42; // OK
const invalidId: ID = true; // ERROR

// Более сложный пример
type Result = 
  | { status: "success"; data: string }
  | { status: "error"; error: string }
  | { status: "loading" };

// Использование
function handleResult(result: Result) {
  if (result.status === "success") {
    console.log(result.data); // TypeScript знает, что data существует
  } else if (result.status === "error") {
    console.log(result.error); // TypeScript знает, что error существует
  }
}

3. Пересечение типов (Intersection Types)

type можно комбинировать, создавая новые типы:

type Animal = {
  name: string;
  age: number;
};

type Dog = Animal & {
  breed: string;
  bark: () => void;
};

const myDog: Dog = {
  name: "Rex",
  age: 3,
  breed: "Labrador",
  bark: () => console.log("Woof!") 
};

4. Условные типы (Conditional Types)

type может содержать логику, как if-else для типов:

// Если T - массив, вернулась элемент, иначе T
type Flatten<T> = T extends Array<infer U> ? U : T;

type Str = Flatten<string[]>; // string
type Num = Flatten<number>; // number

// Практический пример
type IsString<T> = T extends string ? true : false;

type A = IsString<"hello">; // true
type B = IsString<42>; // false

5. Универсальные типы (Generics)

type работает с generic параметрами, делая код переиспользуемым:

// Generic тип для API ответа
type ApiResponse<T> = {
  status: number;
  data: T;
  message?: string;
};

// Использование с разными типами данных
type UserResponse = ApiResponse<{ id: number; name: string }>;
type PostResponse = ApiResponse<{ id: number; title: string }>;

const userApi: UserResponse = {
  status: 200,
  data: { id: 1, name: "Alice" }
};

const postApi: PostResponse = {
  status: 200,
  data: { id: 1, title: "Hello World" }
};

6. Литеральные типы (Literal Types)

type для строго определённых значений:

// Только эти конкретные значения разрешены
type Direction = "up" | "down" | "left" | "right";

// Использование
function move(direction: Direction) {
  // ...
}

move("up"); // OK
move("diagonal"); // ERROR

// С числами
type StatusCode = 200 | 404 | 500;

const code: StatusCode = 200; // OK
const badCode: StatusCode = 201; // ERROR

7. Mapped Types (Преобразование типов)

type может автоматически генерировать новые типы из существующих:

// Сделай все поля необязательными
type Partial<T> = {
  [K in keyof T]?: T[K];
};

type User = { id: number; name: string; email: string };
type PartialUser = Partial<User>;
// Результат: { id?: number; name?: string; email?: string }

// Сделай все поля readonly
type Readonly<T> = {
  readonly [K in keyof T]: T[K];
};

type ReadonlyUser = Readonly<User>;
// Результат: { readonly id: number; readonly name: string; ... }

// Получи только значения определённого типа
type StringPropertiesOnly<T> = {
  [K in keyof T as T[K] extends string ? K : never]: T[K]
};

type User = { id: number; name: string; email: string };
type StringFields = StringPropertiesOnly<User>;
// Результат: { name: string; email: string }

8. Типы для React компонентов

// Props для компонента
type ButtonProps = {
  label: string;
  onClick: (event: React.MouseEvent<HTMLButtonElement>) => void;
  disabled?: boolean;
  variant?: "primary" | "secondary";
};

export function Button({ label, onClick, disabled, variant = "primary" }: ButtonProps) {
  return (
    <button
      onClick={onClick}
      disabled={disabled}
      className={`button button-${variant}`}
    >
      {label}
    </button>
  );
}

// Типы для useState
type FormState = {
  name: string;
  email: string;
  agreed: boolean;
};

const [form, setForm] = useState<FormState>({
  name: "",
  email: "",
  agreed: false
});

9. Индексные сигнатуры (Index Signatures)

type для объектов с динамическими ключами:

// Объект, где ключи - строки, значения - числа
type NumberMap = {
  [key: string]: number;
};

const scores: NumberMap = {
  "alice": 100,
  "bob": 85,
  "charlie": 92
};

scores["dave"] = 75; // OK
scores["eve"] = "ninety"; // ERROR: не число

Типы vs Интерфейсы

Когда использовать type vs interface:

// interface - для объектов и классов (может наследоваться)
interface User {
  id: number;
  name: string;
}

interface Admin extends User {
  permissions: string[];
}

// type - для всего остального
type ID = string | number;
type Callback = (data: string) => void;
type Result = Success | Error;

// Но можно и type для объектов
type UserType = {
  id: number;
  name: string;
};

type AdminType = UserType & {
  permissions: string[];
};

Практический пример: API с типами

// Определи типы для API
type ApiUser = {
  id: number;
  name: string;
  email: string;
  createdAt: string;
};

type ApiResponse<T> = {
  status: "success" | "error";
  data?: T;
  error?: string;
};

// Функция с типами
async function fetchUser(id: number): Promise<ApiResponse<ApiUser>> {
  const response = await fetch(`/api/users/${id}`);
  return response.json();
}

// Использование
const result = await fetchUser(1);
if (result.status === "success") {
  console.log(result.data?.name); // TypeScript знает, что data существует
}

Итог

type в TypeScript используется для:

  • Описания формы данных (объекты, массивы, функции)
  • Ловли ошибок на этапе разработки (до запуска кода)
  • Улучшения IDE автодополнения (IntelliSense)
  • Документирования кода (самодокументирующийся код)
  • Создания переиспользуемых типов (generics, mapped types)
  • Улучшения команды (все знают, какие данные где)

Основное правило: если используешь TypeScript, используй type (или interface) везде. Это экономит часы отладки!

Для чего можно использовать тип? | PrepBro