keyof и typeof
keyof
Возвращает union всех ключей типа:
type User = {
name: string;
age: number;
email: string;
};
type UserKeys = keyof User;
// 'name' | 'age' | 'email'
Использование
Безопасный доступ к свойству
function getValue<T, K extends keyof T>(obj: T, key: K): T[K] {
return obj[key];
}
const user = { name: 'Алиса', age: 25 };
getValue(user, 'name'); // string
getValue(user, 'age'); // number
getValue(user, 'xxx'); // ошибка
Проверка ключа
function hasKey<T extends object>(obj: T, key: string): key is keyof T {
return key in obj;
}
Ключи для обновления
function update<T, K extends keyof T>(obj: T, key: K, value: T[K]): T {
return { ...obj, [key]: value };
}
update(user, 'name', 'Боб'); // ок
update(user, 'name', 42); // ошибка
keyof на массиве
type Arr = string[];
type Keys = keyof Arr;
// number | 'length' | 'push' | 'pop' | ...
keyof на union
type A = { a: string };
type B = { b: number };
type Keys = keyof (A | B); // never
Для union — только общие ключи. У A | B общих нет.
keyof с пересечением
type Keys = keyof (A & B);
// 'a' | 'b'
typeof
Возвращает тип значения:
const user = { name: 'Алиса', age: 25 };
type User = typeof user;
// { name: string; age: number }
typeof функции
function add(a: number, b: number) {
return a + b;
}
type Add = typeof add;
// (a: number, b: number) => number
Комбинация
const config = {
apiUrl: 'https://api.example.com',
timeout: 5000,
};
type Config = typeof config;
type ConfigKey = keyof typeof config;
// 'apiUrl' | 'timeout'
as const
const STATUS = {
IDLE: 'idle',
LOADING: 'loading',
SUCCESS: 'success',
} as const;
type Status = typeof STATUS[keyof typeof STATUS];
// 'idle' | 'loading' | 'success'
as const делает значения литеральными, а keyof typeof даёт union.
Практика: enum через объект
export const Role = {
Admin: 'admin',
User: 'user',
Guest: 'guest',
} as const;
export type Role = typeof Role[keyof typeof Role];
- Есть объект для итерации
- Есть тип
- Нет runtime-кода как у enum
Практика: ключи формы
type Form = {
name: string;
email: string;
password: string;
};
function validateField(field: keyof Form, value: string) {
// ...
}
validateField('name', 'Алиса'); // ок
validateField('xxx', 'А'); // ошибка
Итоги
keyof— union ключейtypeof— тип значенияT[K]— тип значения по ключу- Комбинация даёт мощные утилиты
as const+keyof typeof— замена enum