Модификаторы в Mapped Types (+, -)

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

Тренажер по TypeScript

Mapped Types (сопоставленные типы) позволяют создавать новые типы на основе старых, перебирая их ключи. Однако часто нам нужно не просто скопировать свойства, но и изменить их модификаторы: readonly (только для чтения) и ? (опциональность).

TypeScript предоставляет синтаксис для добавления (+) или удаления (-) этих модификаторов. Например, запись -readonly удаляет ограничение на запись, делая свойство изменяемым, а -? делает свойство обязательным, удаляя undefined из типа.

В этом тренажере вы попрактикуетесь в управлении модификаторами внутри Mapped Types для создания гибких утилитных типов.

Список тем

1. Значение модификаторов

id: 40748_ts_mapped_mods_compare_01

В левой колонке приведены синтаксические конструкции модификаторов, используемых в Mapped Types TypeScript. В правой колонке — описания их действий. Сопоставьте каждый модификатор с соответствующим описанием. Обратите внимание, что в правой колонке описания перемешаны, и каждому модификатору соответствует ровно одно правильное действие.

Сопоставьте строки в правой(нижней) части с соответствующими строками в левой(верхней) по порядковому номеру
-?
+?
-readonly
+readonly
Делает свойство необязательным (добавляет опциональность)
Делает свойство обязательным (удаляет опциональность)
Удаляет модификатор readonly (свойство становится изменяемым)
Добавляет модификатор readonly (свойство становится только для чтения)
Сообщения
Проверить
Показать подсказку

2. Удаление опциональности

id: 40748_ts_mapped_mods_replace_02

В этом задании вам предстоит поработать с mapped types в TypeScript, а именно с модификаторами для удаления опциональности. Имеется тип Person с опциональными полями. Ваша задача — дополнить определение типа Required, который должен преобразовывать все опциональные поля исходного типа в обязательные. Для этого в mapped type необходимо применить соответствующий модификатор. Вставьте пропущенный фрагмент так, чтобы код стал корректным и тип Required делал все поля обязательными.

Заполните пропуски
type Person = {
  name?: string;
  age?: number;
};

type Required<T> = {
  [P in keyof T] input1S : T[P];
};

const person: Required<Person> = {
  name: "Alice",
  age: 30
};
Сообщения
Проверить
Показать решение на 3 сек.
Показать подсказку

3. Создание Mutable типа

id: 40748_ts_mapped_mods_select_03

В этом задании вам нужно создать mapped type, который преобразует все поля переданного типа из readonly в изменяемые. Для этого необходимо выбрать правильный модификатор из выпадающего списка, чтобы убрать модификатор readonly. Обратите внимание на синтаксис mapped types и использование модификаторов + и -.

Нужно правильно расставить в пропуски предложенные варианты
type ReadonlyPoint = {
  readonly x: number;
  readonly y: number;
};

type Mutable<T> = {
  input1S [P in keyof T]: T[P]
};

type Point = Mutable<ReadonlyPoint>;
// Теперь Point должен быть { x: number; y: number; } без readonly
Сообщения
Проверить
Показать решение на 3 сек.
Показать подсказку

4. Конструктор типов

id: 40748_ts_mapped_mods_build_04

Из предложенных строк соберите корректное определение типа TypeScript, который делает все поля объекта только для чтения (readonly) и обязательными (удаляет опциональность). Используйте mapped types с модификаторами + и -. Некоторые строки лишние и не должны входить в решение.

Перетяните в правильном порядке строки из одного блока в другой
type ReadonlyRequired<T> =
{
+readonly
[P in keyof T]
-?
T[P];
}
readonly
[P in keyof T]?
T[P]
Сообщения
Проверить
Показать решение на 3 сек.
Показать подсказку

5. Результат трансформации

id: 40748_ts_mapped_mods_predict_05

Проанализируйте приведённый фрагмент кода TypeScript. Исходный интерфейс содержит опциональные поля. Используется mapped type с модификатором '-?'. Определите, как будет выглядеть итоговый тип после трансформации. Выберите правильное описание результирующего типа.

Выберите правильный вариант ответа
// Исходный интерфейс с опциональными полями
interface UserProfile {
    id?: number;
    username?: string;
    email?: string;
    isActive?: boolean;
}

// Mapped type с модификатором '-?'
type RequiredUserProfile = {
    [K in keyof UserProfile]-?: UserProfile[K];
};

// Пример использования
// const profile: RequiredUserProfile = { ... };
Сообщения
Проверить
Показать подсказку

6. Логика работы Mapped Type

id: 40748_ts_mapped_mods_analyze_06

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

type MutableRequired<T> = {
  -readonly [P in keyof T]-?: T[P]
};

interface User {
  readonly id: number;
  name?: string;
  readonly email?: string;
}

type MutableUser = MutableRequired<User>;
Расположите элементы в логичном порядке
Формируется новый тип MutableUser, где все поля обязательные и изменяемые
Исходный тип User содержит поля: id (readonly, обязательное), name (опциональное), email (readonly и опциональное)
Для каждого ключа удаляется опциональность (применяется суффикс -?)
Для каждого ключа удаляется модификатор readonly (применяется префикс -readonly)
Компилятор получает все ключи типа User с помощью keyof: "id" | "name" | "email"
Сообщения
Проверить
Показать подсказку

7. Ошибка синтаксиса

id: 40748_ts_mapped_mods_error_07

В данном фрагменте кода TypeScript используется mapped type с модификаторами, но допущена синтаксическая ошибка в указании модификатора. Исправьте строку с ошибкой, чтобы mapped type корректно применял модификаторы к свойствам типа.

Найдите ошибку и исправьте
type User = {
    name: string;
    age: number;
};
type ReadonlyUser = { readonly- [K in keyof User]: User[K] };
Сообщения
Проверить
Показать решение на 3 сек.
Показать подсказку

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

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