Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Для чего можно использовать 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) везде. Это экономит часы отладки!