Generic Constraints (extends)

Тренажер по TypeScript для пользователей с начальным уровнем подготовки.

Тренажер по TypeScript

В TypeScript Generics (Обобщения) по умолчанию могут принимать любой тип. Однако иногда нам нужно работать со свойствами, которые присущи только определенному набору типов (например, свойство .length у массивов и строк). Для этого используются Generic Constraints (Ограничения обобщений).

Ключевое слово extends позволяет сузить допустимый диапазон типов. Синтаксис: . Это говорит компилятору: «Тип T может быть любым, но он обязан иметь структуру, совместимую с SomeInterface». Если попытаться передать тип, не удовлетворяющий ограничению, TypeScript выдаст ошибку. Это делает код более безопасным и предсказуемым, позволяя обращаться к свойствам ограничения внутри функции.

Список тем

1. Ключевое слово ограничения

id: 40717_gc_replace_extends

В этом задании вам нужно дополнить объявление обобщённой функции, которая работает с объектами, имеющими свойство `id`. Для корректной типизации необходимо ограничить тип-параметр, чтобы он гарантированно содержал поле `id` определённого типа. Впишите в указанное место ключевое слово, которое в TypeScript используется для наложения ограничений на дженерики. После правильного заполнения пропуска функция сможет принимать только объекты с `id: number` и выводить значение этого идентификатора.

Заполните пропуски
function printId<T input1S { id: number }>(obj: T): void {
    console.log(obj.id);
}

const user = { id: 42, name: 'Alice' };
printId(user);
Сообщения
Проверить
Показать решение на 3 сек.
Показать подсказку

2. Разметка ограничения

id: 40717_gc_highlight_parts_constraint

Разметьте сигнатуру функции с ограничением обобщённого типа (generic constraint) в TypeScript. Укажите для каждого выделенного фрагмента, является ли он параметром типа (T), ключевым словом ограничения (extends) или типом-ограничением (интерфейсом). Это упражнение поможет закрепить понимание синтаксиса ограничений в дженериках.

Кликните по каждому выделенному фрагменту и выберите для него подходящий тип из списка под текстом.
function logLength<{{T~|~t1}} {{extends~|~t2}} {{Lengthwise~|~t3}}>(arg: T): void {
  console.log(arg.length);
}
Параметр типа (T)
Тип-ограничение (интерфейс)
Ключевое слово ограничения (extends)
Сообщения
Проверить
Показать подсказку

3. Доступ к свойству без ограничения

id: 40717_gc_error_property_access

В этом фрагменте кода TypeScript определена обобщённая функция, которая пытается получить доступ к свойству .value у объекта типа T. Однако в сигнатуре функции отсутствует необходимое ограничение, что приводит к ошибке компиляции. Исправьте объявление функции, добавив ограничение на тип T, чтобы гарантировать наличие свойства value.

Найдите ошибку и исправьте
function getValue<T>(obj: T): any {
    return obj.value;
}
 
const num = getValue({ value: 42 });
console.log(num);
Сообщения
Проверить
Показать решение на 3 сек.
Показать подсказку

4. Выбор правильного интерфейса

id: 40717_gc_select_fill_interface

В этом задании вам предстоит дополнить код функции, которая выводит имя пользователя. Для этого необходимо выбрать подходящий интерфейс для ограничения дженерика (extends), чтобы гарантировать наличие поля 'name' у передаваемого объекта. Также нужно указать, какое свойство следует выводить. Используйте выпадающие списки для заполнения пропусков в коде.

Нужно правильно расставить в пропуски предложенные варианты
interface Person {
  name: string;
  age: number;
}

interface Animal {
  species: string;
}

interface Named {
  name: string;
}

function printName<T extends input1S>(obj: T): void {
  console.log(obj.input2S);
}

const user = { name: 'Alice', age: 30 };
printName(user);
Сообщения
Проверить
Показать решение на 3 сек.
Показать подсказку

5. Логика проверки ограничения

id: 40717_gc_analyze_flow

Проанализируйте TypeScript-код сверху и восстановите последовательность логических шагов, которые выполняет компилятор при вызове функции с ограниченным дженериком (generic constraint). Шаги снизу перемешаны — расставьте их в правильном порядке, чтобы отразить процесс проверки типа и выполнения функции.

interface HasLength {
  length: number;
}

function getLength<T extends HasLength>(obj: T): number {
  return obj.length;
}

const result = getLength("TypeScript");
console.log(result);
Расположите элементы в логичном порядке
Успешная проверка: тип T выводится как string, так как строка удовлетворяет интерфейсу HasLength
Вызов функции getLength с аргументом строки "TypeScript"
Объявление функции getLength с ограничением дженерика T extends HasLength
Вывод результата (число 10) в консоль
Выполнение тела функции: возврат значения obj.length (для строки "TypeScript" это 10)
Проверка компилятором: соответствует ли тип аргумента (string) ограничению HasLength (имеет свойство length: number)
Сообщения
Проверить
Показать подсказку

6. Сборка функции с ограничением

id: 40717_gc_build_signature

Из предложенных строк соберите корректную сигнатуру стрелочной функции на TypeScript, которая использует дженерик T, ограниченный типами number или string (включая строковые литералы). Функция должна принимать параметр типа T и возвращать значение того же типа. Игнорируйте лишние строки, которые нарушают ограничение или используют неправильный синтаксис.

Перетяните в правильном порядке строки из одного блока в другой
const myFunc = <T extends string | number>
(value: T): T =>
value;
const myFunc = <T>
(value: T): T =>
const myFunc = <T extends boolean>
(value: any): any =>
Сообщения
Проверить
Показать решение на 3 сек.
Показать подсказку

TypeScript: компиляция и запуск

id: 40717_compiler

Этот тренажер показывает как использовать ограничения (extends) в TypeScript дженериках. Вы увидите, как ограничить типы, которые можно использовать с дженериками, чтобы обеспечить безопасность типов. Попробуйте: измените типы объектов, добавьте свои свойства в интерфейсы, создайте новые функции с ограничениями. Экспериментируйте с разными типами — посмотрите, что произойдет, если передать объект без обязательных свойств!

TS
Запустить тренажёр (TypeScript)
НайтиКурс.Ру