Вопрос проверяет умение заставить TypeScript строго контролировать доступ к свойствам объекта и предотвращать ошибки на этапе компиляции.
Чтобы TypeScript ругался на несуществующий ключ, нужно ограничить ключи через keyof и не использовать тип string или any. Если ключ типизирован как keyof T, компилятор разрешит доступ только к реально существующим свойствам объекта. Любая попытка передать невалидный ключ вызовет ошибку на этапе проверки типов. Это основной механизм типобезопасного доступа к объектам.
По умолчанию TypeScript может быть слишком «мягким», если дать ему слишком общий тип ключа.
keyof — оператор TypeScript, который формирует объединение всех допустимых ключей объекта.
keyoffunction get(obj: { a: number }, key: string) {
return obj[key];
}
TypeScript не знает, существует ли такой ключ.
Нет ошибки даже для get(obj, "b").
Тип результата становится небезопасным (any или unknown).
keyoffunction get<T, K extends keyof T>(obj: T, key: K): T[K] {
return obj[key];
}
const user = { id: 1, name: "Alex" };
get(user, "id"); // ok
get(user, "name"); // ok
get(user, "age"); // ошибка TypeScript
type User = {
id: number;
name: string;
};
function getUserValue(user: User, key: keyof User) {
return user[key];
}
Включить noImplicitAny.
Включить strict.
Избегать индексных сигнатур без необходимости.
// ослабляет контроль
type Bad = {
[key: string]: string;
};
Чтобы TypeScript гарантированно ругался на несуществующие ключи, ключ всегда должен быть типизирован через keyof, а не как произвольная строка.