Какие типы данных поддерживаются в TypeScript?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Какие типы данных поддерживаются в TypeScript?
TypeScript расширяет JavaScript, добавляя систему типов. Это предотвращает большинство типов ошибок на этапе компиляции, а не в runtime. Для фронтенд-разработчика понимание типов критично для написания надежного и maintainable кода.
1. Примитивные типы
number — числа:
const age: number = 25;
const pi: number = 3.14;
const hex: number = 0xff;
const negative: number = -42;
// Специальные значения
const infinity: number = Infinity;
const notANumber: number = NaN;
string — строки:
const name: string = 'Alice';
const greeting: string = "Hello, world!";
const template: string = `Hello, ${name}`;
boolean — логические значения:
const isActive: boolean = true;
const isEmpty: boolean = false;
const hasError: boolean = !true; // false
null и undefined:
const noValue: null = null;
const notDefined: undefined = undefined;
// По умолчанию null и undefined — подтипы других типов
// Но с strictNullChecks это меняется
const value: string = null; // Ошибка при strictNullChecks
any — любой тип (ИЗБЕГАЙ!):
const anything: any = 42;
anything = 'string';
anything.unknownMethod(); // Ошибок при компиляции нет
// ❌ Плохо — теряется преимущество типов
// ✅ Лучше используй unknown
unknown — тип неизвестного значения:
const value: unknown = 42;
// ❌ Не можешь использовать напрямую
// value.toFixed(); // Ошибка!
// ✅ Нужна проверка типа (type guard)
if (typeof value === 'number') {
value.toFixed(2); // OK
}
2. Объекты и интерфейсы
type — определение типа объекта:
type User = {
name: string;
age: number;
email?: string; // Опциональное поле
readonly id: number; // Только для чтения
};
const user: User = {
name: 'Alice',
age: 30,
id: 1
};
// user.id = 2; // Ошибка! readonly
interface — определение контракта:
interface Animal {
name: string;
age: number;
makeSound(): void;
}
const dog: Animal = {
name: 'Rex',
age: 5,
makeSound() {
console.log('Woof!');
}
};
Разница между type и interface:
// interface можно расширять
interface User {
name: string;
}
interface User {
email: string; // Будут объединены
}
// type нельзя расширять (нужен объединение)
type User = { name: string };
// type User = { ...User, email: string }; // Ошибка!
// Для type используй пересечение (&)
type UserWithEmail = User & { email: string };
3. Объединения (Union Types)
Union — значение может быть одного из нескольких типов:
type Status = 'success' | 'error' | 'pending';
const result: Status = 'success'; // OK
// const invalid: Status = 'invalid'; // Ошибка!
// Union с типами
type NumberOrString = number | string;
const value: NumberOrString = 42; // OK
const value2: NumberOrString = 'hello'; // OK
Discriminated Union (Discriminated Union Types):
type Result =
| { status: 'success'; data: string }
| { status: 'error'; error: string };
function handleResult(result: Result) {
if (result.status === 'success') {
console.log(result.data); // TypeScript знает, что здесь data
} else {
console.log(result.error); // И здесь error
}
}
4. Пересечения (Intersection Types)
Intersection — объединяет несколько типов:
type Admin = {
isAdmin: boolean;
adminPanel(): void;
};
type User = {
name: string;
email: string;
};
// AdminUser должен иметь оба типа
type AdminUser = Admin & User;
const adminUser: AdminUser = {
isAdmin: true,
adminPanel() {},
name: 'Alice',
email: 'alice@example.com'
};
5. Массивы
Типы массивов:
// Способ 1
const numbers: number[] = [1, 2, 3];
const strings: string[] = ['a', 'b', 'c'];
// Способ 2 — generic синтаксис
const numbers2: Array<number> = [1, 2, 3];
// Массив разных типов
const mixed: (number | string)[] = [1, 'two', 3];
// Массив объектов
interface User { name: string; }
const users: User[] = [
{ name: 'Alice' },
{ name: 'Bob' }
];
// Кортеж (tuple) — массив фиксированной длины
const tuple: [string, number] = ['hello', 42];
// tuple = [42, 'hello']; // Ошибка!
6. Функции
Типизация функции:
// Способ 1 — inline типы
function add(a: number, b: number): number {
return a + b;
}
// Способ 2 — type для функции
type Add = (a: number, b: number) => number;
const add: Add = (a, b) => a + b;
// Способ 3 — interface
interface Calculator {
add(a: number, b: number): number;
subtract(a: number, b: number): number;
}
// Опциональные параметры
function greet(name: string, age?: number) {
console.log(`Hello, ${name}`);
if (age !== undefined) {
console.log(`Age: ${age}`);
}
}
// Параметры по умолчанию
function repeat(text: string, times: number = 3): string {
return text.repeat(times);
}
// Rest параметры
function sum(...numbers: number[]): number {
return numbers.reduce((a, b) => a + b, 0);
}
7. Generics (Обобщенные типы)
Позволяют использовать тип как параметр:
// Базовый generic
function identity<T>(value: T): T {
return value;
}
const num = identity<number>(42); // OK
const str = identity<string>('hello'); // OK
// Generic с interface
interface Box<T> {
content: T;
getContent(): T;
}
const numberBox: Box<number> = {
content: 42,
getContent() { return this.content; }
};
// Generic с массивом
function getFirstItem<T>(items: T[]): T | undefined {
return items[0];
}
const first = getFirstItem([1, 2, 3]); // number | undefined
Constraints (Ограничения на generics):
// T должен быть объектом с свойством name
function getName<T extends { name: string }>(obj: T): string {
return obj.name;
}
getName({ name: 'Alice' }); // OK
// getName(42); // Ошибка!
8. Literal типы
Точное значение, не тип:
// String literal
type Direction = 'up' | 'down' | 'left' | 'right';
const direction: Direction = 'up'; // OK
// const invalid: Direction = 'invalid'; // Ошибка!
// Number literal
type DiceRoll = 1 | 2 | 3 | 4 | 5 | 6;
// Boolean literal
type Enabled = true;
const enabled: Enabled = true; // OK
// const disabled: Enabled = false; // Ошибка!
9. Utility типы
TypeScript предоставляет встроенные utility типы:
Partial<T> — все свойства опциональны:
interface User {
name: string;
email: string;
}
type PartialUser = Partial<User>;
// { name?: string; email?: string; }
Required<T> — все свойства обязательны:
type RequiredUser = Required<PartialUser>;
// { name: string; email: string; }
Readonly<T> — все свойства readonly:
type ReadonlyUser = Readonly<User>;
// { readonly name: string; readonly email: string; }
Pick<T, K> — выбери определенные свойства:
type UserPreview = Pick<User, 'name'>;
// { name: string; }
Omit<T, K> — исключи определенные свойства:
type UserWithoutEmail = Omit<User, 'email'>;
// { name: string; }
Record<K, T> — создай объект с определенными ключами:
type Status = 'success' | 'error' | 'pending';
type StatusCount = Record<Status, number>;
// { success: number; error: number; pending: number; }
10. Type Guards (Проверка типов)
typeof — проверка примитивных типов:
function process(value: string | number) {
if (typeof value === 'string') {
value.toUpperCase(); // OK, это string
} else {
value.toFixed(2); // OK, это number
}
}
instanceof — проверка класса:
class Dog {
bark() { }
}
function makeSound(animal: Dog | string) {
if (animal instanceof Dog) {
animal.bark(); // OK, это Dog
}
}
Custom type guard:
function isUser(obj: any): obj is User {
return typeof obj === 'object' && 'name' in obj && 'email' in obj;
}
const data: unknown = { name: 'Alice', email: 'alice@example.com' };
if (isUser(data)) {
console.log(data.name); // OK, TypeScript знает, что это User
}
Сравнение типов
| Тип | Пример | Использование |
|---|---|---|
| number | 42, 3.14, Infinity | Числа |
| string | 'hello', "world" | Текст |
| boolean | true, false | Логика |
| null | null | Отсутствие значения |
| undefined | undefined | Неопределено |
| any | anything | ИЗБЕГАЙ! |
| unknown | unknown | Безопасный any |
| type | type User = {} | Структура |
| interface | interface User {} | Контракт |
| Union | number | string | Несколько типов |
| Intersection | Type1 & Type2 | Объединение |
| Array | number[] | Список |
| Tuple | [string, number] | Фиксированный список |
| Generic | <T> | Переиспользуемые типы |
Лучшие практики
- Используй strict mode:
{
"compilerOptions": {
"strict": true,
"strictNullChecks": true
}
}
- Избегай any:
// ❌
const data: any = fetchData();
// ✅
const data: unknown = fetchData();
if (typeof data === 'object') { /* ... */ }
- Используй readonly для иммутабельности:
interface User {
readonly id: number;
name: string;
}
- Предпочитай type guards:
function isString(value: unknown): value is string {
return typeof value === 'string';
}
Чек-лист
- Примитивные типы: number, string, boolean, null, undefined
- Objects и interfaces
- Union (|) и Intersection (&) типы
- Массивы и кортежи
- Функции с типами
- Generics для переиспользуемых типов
- Literal типы
- Utility типы (Partial, Required, Pick, Omit)
- Type guards
- Избегаю any, использую unknown
Вывод: TypeScript типы — это мощный инструмент для предотвращения ошибок. Правильное использование типов делает код более безопасным, читаемым и maintainable. Инвестируй время в изучение системы типов — это окупится многократно.