> Как реализовать функцию getProperty с типизацией в TypeScript, которая возвращает значение по ключу объекта? (TypeScript)

Уровень: senior · Роль: frontend · Категория: Технические вопросы

Компании: Иннотех, КИТМЕД, IT-One, RecruitTech, Altenar

Стек: TypeScript

> Пример ответа

Короткий ответ

Для реализации getProperty с типизацией используйте дженерики и keyof: function getProperty<T, K extends keyof T>(obj: T, key: K): T[K]. Это гарантирует, что ключ существует в объекте, а возвращаемый тип соответствует типу значения по этому ключу. Для безопасной работы с опциональными или вложенными полями можно добавить проверки и использовать Partial или Record.

Подробное объяснение

Типизация getProperty строится на двух ключевых механизмах TypeScript: дженериках и операторе keyof. Дженерик T представляет тип объекта, а K extends keyof T ограничивает второй параметр только существующими ключами объекта. Возвращаемый тип T[K] - это lookup type, который выводит точный тип значения по указанному ключу.

Без такой типизации функция могла бы принимать любую строку в качестве ключа, что приводит к ошибкам времени выполнения. TypeScript в данном случае обеспечивает compile-time проверку: если ключ не существует в объекте, код не скомпилируется.

Для edge cases, например, когда объект может быть null или undefined, стоит добавить проверки внутри функции. Для работы с вложенными объектами можно создать рекурсивную типизацию с использованием conditional types.

На практике

В реальных проектах getProperty часто используется при работе с API-ответами, где структура данных известна, но может меняться. Типизация помогает избежать ошибок при рефакторинге: если поле переименовали или удалили, TypeScript укажет на все места использования.

Для сложных случаев, когда ключ может быть динамическим (например, из массива), используйте keyof typeof или as const для сужения типа. Для опциональных полей применяйте Partial<T> или T[K] | undefined в возвращаемом типе.

Пример кода

TYPESCRIPT
// Базовая реализация
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
return obj[key];
}
// Пример использования
interface User {
id: number;
name: string;
email?: string;
}
const user: User = { id: 1, name: 'Alice' };
const name = getProperty(user, 'name'); // string
const id = getProperty(user, 'id'); // number
// const invalid = getProperty(user, 'age'); // Ошибка компиляции
// С проверкой на null/undefined
function getPropertySafe<T, K extends keyof T>(
obj: T | null | undefined,
key: K
): T[K] | undefined {
return obj?.[key];
}
// Для вложенных объектов
type NestedKey<T, K extends keyof T> = T[K] extends object
? keyof T[K]
: never;

Как отвечать на собеседовании

Начните с простого решения через дженерики и keyof, затем объясните, зачем это нужно: безопасность типов, автокомплит в IDE, защита от опечаток. Покажите, как TypeScript выводит точный тип возвращаемого значения. Упомяните, что для динамических ключей (например, из Object.keys) нужны дополнительные проверки, так как TypeScript не может гарантировать существование ключа в runtime.

Если собеседник спросит про сложные случаи, расскажите про conditional types для вложенных объектов, про as const для сужения литеральных типов и про satisfies оператор в TypeScript 4.9+.

Что проверяет интервьюер

Интервьюер оценивает понимание:

  • дженериков и их ограничений
  • оператора keyof и lookup types
  • разницы между compile-time и runtime проверками
  • работы с опциональными и вложенными полями
  • практического применения типизации в реальных проектах

Также проверяется способность объяснить trade-off между строгостью типов и гибкостью кода.

Типичные ошибки

  • Использование any для ключа или возвращаемого значения - убивает всю пользу от типизации
  • Игнорирование случая, когда объект может быть null или undefined
  • Попытка использовать Object.keys(obj) для динамического доступа - TypeScript не может вывести тип ключа
  • Забывание про readonly поля - keyof включает их, но модификация может быть запрещена
  • Слишком сложная типизация для простых случаев - не стоит использовать conditional types там, где достаточно базового keyof

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью