Keyof в TypeScript
keyof — это ключевое слово TypeScript. Оно принимает тип объекта и возвращает тип его ключей.
keyof с явно перечисленными ключами
Когда вы применяете keyof к типу объекта, свойства которого перечислены по именам, результатом будет объединение (union) из этих имён свойств.
Пример
keyof Person превращается в объединение "name" | "age". Передача функции любой другой строки — ошибка.
Prompt
Покажите, как
keyof, применённый к интерфейсу с именованными свойствами, даёт объединение этих имён свойств.
Объявите интерфейс Person с полями name: string и age: number, напишите функцию, которая принимает Person и имя свойства типа keyof Person и выводит значение этого свойства, затем вызовите её с человеком по имени Max, возраст 27, и свойством "name".
Вывод: программа на TypeScript и захваченный вывод
script.ts
interface Person {
name: string;
age: number;
}
// `keyof Person` здесь создаёт тип-объединение из "name" и "age", другие строки не допускаются
function printPersonProperty(person: Person, property: keyof Person) {
console.log(`Вывожу свойство человека ${property}: "${person[property]}"`);
}
let person = {
name: "Max",
age: 27
};
printPersonProperty(person, "name"); // Вывожу свойство человека name: "Max"
keyof с индексными сигнатурами
keyof работает и с типами, у которых есть индексная сигнатура. В этом случае оно возвращает тип индекса.
Пример
Поскольку StringMap принимает любой строковый ключ, keyof StringMap — это просто string.
Prompt
Покажите, что
keyof, применённый к типу со строковой индексной сигнатурой, сводится к string.
Определите тип StringMap с индексной сигнатурой [key: string]: unknown и функцию, которая принимает ключ типа keyof StringMap и строковое значение и возвращает новый StringMap с этой парой; пример только объявляет их и ничего не печатает.
Вывод: программа на TypeScript и захваченный вывод
script.ts
type StringMap = { [key: string]: unknown };
// `keyof StringMap` здесь сводится к `string`
function createStringPair(property: keyof StringMap, value: string): StringMap {
return { [property]: value };
}