← Назад к вопросам
Как обеспечить поддержку шрифтов на старых устройствах?
2.0 Middle🔥 91 комментариев
#HTML и CSS#Оптимизация и производительность
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI3 апр. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Ограничение Generic параметров в TypeScript
Ограничение Generic параметров (Generic Constraints) позволяет указать, какие типы могут быть переданы в качестве параметра типа. Это обеспечивает типизацию и предотвращает передачу несовместимых типов.
1. Основной синтаксис - extends
Для ограничения Generic используется ключевое слово extends:
// Ограничение на объект
function printObject<T extends object>(obj: T): void {
console.log(obj);
}
printObject({ name: 'John' }); // OK
printObject('string'); // Ошибка: string не является object
// Ограничение на конкретный тип
function getId<T extends { id: number }>(item: T): number {
return item.id;
}
getId({ id: 1, name: 'John' }); // OK
getId({ name: 'John' }); // Ошибка: свойство 'id' отсутствует
2. Ограничение на встроенные типы
// Только строки и числа
function process<T extends string | number>(value: T): T {
return value;
}
process('hello'); // OK
process(42); // OK
process(true); // Ошибка: boolean не в union
// Только массивы
function getLength<T extends any[]>(arr: T): number {
return arr.length;
}
getLength([1, 2, 3]); // OK
getLength('string'); // Ошибка: string[] ожидается
// Только функции
function executeFunction<T extends (...args: any[]) => any>(fn: T): any {
return fn();
}
executeFunction(() => 'test'); // OK
executeFunction('not a function'); // Ошибка
3. Ограничение на класс и его наследников
class Animal {
name: string = '';
move() { console.log('Moving'); }
}
class Dog extends Animal {
bark() { console.log('Woof'); }
}
// Принимает только Animal или его наследников
function createInstance<T extends Animal>(constructor: new () => T): T {
return new constructor();
}
const dog = createInstance(Dog); // OK
const animal = createInstance(Animal); // OK
class NotAnimal {}
const notAnimal = createInstance(NotAnimal); // Ошибка
4. Ограничение с keyof
Ограничение Generic параметра на ключи объекта:
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
return obj[key];
}
const person = { name: 'John', age: 30 };
getProperty(person, 'name'); // OK, возвращает string
getProperty(person, 'age'); // OK, возвращает number
getProperty(person, 'email'); // Ошибка: 'email' не в ключах person
5. Множественные ограничения (Intersection)
interface HasName {
name: string;
}
interface HasAge {
age: number;
}
// Требует оба интерфейса
function describePerson<T extends HasName & HasAge>(person: T): string {
return `${person.name} is ${person.age} years old`;
}
describePerson({ name: 'John', age: 30 }); // OK
describePerson({ name: 'John' }); // Ошибка: age отсутствует
6. Условные типы и Generic
// Распределительные типы
type IsString<T> = T extends string ? true : false;
type A = IsString<'hello'>; // true
type B = IsString<number>; // false
// Практический пример
function processValue<T extends string | number>(
value: T
): T extends string ? string : number {
if (typeof value === 'string') {
return value.toUpperCase() as any;
}
return (value * 2) as any;
}
7. Ограничение с использованием Record
// Объект с определённой структурой
function validateConfig<T extends Record<string, any>>(
config: T
): T {
for (const key in config) {
if (config[key] === undefined) {
throw new Error(`Missing required field: ${key}`);
}
}
return config;
}
const config = validateConfig({
api: 'https://api.example.com',
timeout: 5000
}); // OK
8. Default Generic параметры
Ограничение с дефолтным значением:
function createArray<T extends string | number = string>(value: T, count: number = 1): T[] {
return Array(count).fill(value);
}
createArray('test'); // T = string
createArray('test', 3); // T = string
createArray(42); // T = number (явное ограничение)
// Практический пример с React компонентом
interface ComponentProps<T = {}> {
data: T;
}
const MyComponent = <T extends object = {}>({ data }: ComponentProps<T>) => {
return <div>{JSON.stringify(data)}</div>;
};
9. Сложный практический пример
type ApiResponse<T extends { id: string | number }> = {
data: T;
status: number;
message: string;
};
function handleResponse<T extends { id: string | number }>(
response: ApiResponse<T>
): T {
if (response.status === 200) {
return response.data;
}
throw new Error(response.message);
}
const user = { id: 1, name: 'John', email: 'john@example.com' };
const result = handleResponse({
data: user,
status: 200,
message: 'Success'
});
// result имеет тип { id: number; name: string; email: string }
10. Generic Constraints для коллекций
// Только объекты, которые можно сериализовать
function serialize<T extends object>(obj: T): string {
return JSON.stringify(obj);
}
// Массив с определённым типом элементов
function findDuplicate<T extends (string | number)[]>(arr: T): T[number] | undefined {
const seen = new Set();
for (const item of arr) {
if (seen.has(item)) return item;
seen.add(item);
}
return undefined;
}
findDuplicate([1, 2, 3, 2]); // OK
findDuplicate(['a', 'b', 'a']); // OK
findDuplicate([1, 'a', true]); // Ошибка: boolean не в ограничении
Ограничение Generic параметров - это мощный инструмент для создания безопасного типизированного кода, который предотвращает ошибки на этапе разработки и улучшает читаемость и поддерживаемость приложения.