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

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

Компании: IT-One

Стек: TypeScript

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

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

Функция getProperty с типизацией и проверкой ключей в TypeScript реализуется через дженерики и keyof. Сигнатура function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] гарантирует, что ключ существует в объекте, а возвращаемый тип соответствует типу значения. Для runtime-проверки на undefined можно добавить key in obj или hasOwnProperty.

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

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

Для runtime-проверки (например, при работе с динамическими данными) нужно добавить guard: if (key in obj) или Object.prototype.hasOwnProperty.call(obj, key). Это защищает от обращения к несуществующим свойствам во время выполнения, когда TypeScript не может гарантировать безопасность (например, при any или внешних данных).

На практике

Типичная реализация для production включает:

  • Дженерик T для объекта и K extends keyof T для ключа
  • Возвращаемый тип T[K] для точного вывода типа
  • Runtime-проверку через key in obj или hasOwnProperty
  • Возврат undefined или выбрасывание ошибки при отсутствии ключа

Для строгой безопасности можно использовать перегрузки или conditional types, но базовая реализация покрывает 90% случаев.

Пример кода

TYPESCRIPT
// Базовая реализация с runtime-проверкой
function getProperty<T extends object, K extends keyof T>(
obj: T,
key: K
): T[K] | undefined {
if (key in obj) {
return obj[key];
}
return undefined;
}
// Использование
interface User {
name: string;
age: number;
email?: string;
}
const user: User = { name: 'Alice', age: 30 };
const name = getProperty(user, 'name'); // string
const age = getProperty(user, 'age'); // number
const email = getProperty(user, 'email'); // string | undefined
// Ошибка компиляции: 'invalid' не является ключом User
// getProperty(user, 'invalid');

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

Начни с базовой сигнатуры getProperty<T, K extends keyof T>(obj: T, key: K): T[K]. Объясни, что keyof создает union ключей, а extends ограничивает допустимые значения. Упомяни, что TypeScript выводит точный тип возвращаемого значения через indexed access. Добавь, что для runtime-безопасности нужна проверка key in obj, особенно при работе с any или внешними данными. Если спросят про edge cases - расскажи про обработку null/undefined объекта и про hasOwnProperty vs in.

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

  • Понимание keyof и indexed access types
  • Умение комбинировать дженерики с ограничениями
  • Знание разницы между compile-time и runtime-проверками
  • Понимание, как TypeScript выводит типы из дженериков
  • Способность предусмотреть edge cases (null, undefined, отсутствие ключа)

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

  • Забывают про runtime-проверку, полагаясь только на TypeScript
  • Используют any вместо дженериков, теряя типизацию
  • Путают key in obj с obj.hasOwnProperty(key) - первое проверяет прототип, второе нет
  • Не обрабатывают случай, когда объект может быть null или undefined
  • Используют as для приведения типа вместо правильной типизации

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

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