Как реализовать функцию getProperty с типизацией в TypeScript, которая возвращает значение по ключу объекта?
Что проверяют
Знаете ли вы keyof и обобщённые ограничения. Это стандартная задача на понимание того, как связать тип аргумента с типом результата.
Как отвечать
Нужны два параметра типа: сам объект и ключ, ограниченный его ключами.
function getProperty<T extends object, K extends keyof T>(obj: T, key: K): T[K] {
return obj[key];
}
const user = { name: "Аня", age: 30 };
const name = getProperty(user, "name"); // string
const age = getProperty(user, "age"); // number
getProperty(user, "email"); // ошибка компиляцииОбъясните, что здесь происходит: keyof T это объединение ключей объекта, K extends keyof T заставляет компилятор запомнить конкретный переданный ключ как литеральный тип, а T[K] это индексированный доступ, дающий тип именно этого поля. Без второго параметра типа результат схлопнулся бы в объединение всех типов значений.
Дальше обычно просят усложнить. Значение по умолчанию:
function getOr<T extends object, K extends keyof T>(obj: T, key: K, fallback: NonNullable<T[K]>): NonNullable<T[K]> {
return obj[key] ?? fallback;
}Или доступ по вложенному пути, где нужны шаблонные литеральные типы и рекурсивный условный тип. Достаточно сказать, что это делается через ` ${K}.${Path<T[K]>} ` и рекурсию, полную реализацию на собеседовании не ждут.
Где спотыкаются
Пишут key: string и теряют связь между аргументом и результатом.
Возвращают any, обнуляя смысл задачи.
Не знают про keyof и предлагают перечислять ключи объединением руками.
Забывают, что типы стираются: проверить существование ключа во время выполнения всё равно придётся, если объект пришёл извне.