In TypeScript, the keyof type operator allows you to obtain the keys of an object and use them to perform various operations. It plays a significant role when working with objects and their properties.
Syntax
The syntax of the keyof type operator in TypeScript is as follows
keyof Type
The keyof keyword is followed by the name of a type, referred to as “Type.” It returns a union type consisting of all the keys (property names) of the specified type. This allows you to access and manipulate an object’s keys dynamically.
Examples
Let’s understand the keyof operator with the help of some examples in TypeScript.
Example 1: Accessing Object Property Names
The keyof keyword helps us retrieve the names of properties defined within an object type.
In this example, we define an interface called “Person” with two properties: “name” of type string and “age” of type number.
Then we create a type alias “PersonKeys” using keyof to extract the keys from the Person interface.
Finally, we assign the value ‘name’ to a constant named “keys” of type PersonKeys and log its value.
interfacePerson{
name: string;
age: number;}
type PersonKeys = keyof Person;const keys: PersonKeys ='name';
console.log(keys);
On compiling, it will generate the following JavaScript code
var keys ='name';
console.log(keys);
Output
The above code will produce the following output
name
Example: Type-Safe Property Access
The keyof keyword enables us to access object properties in a type-safe manner.
In this example, we define an interface “Car” with properties representing a car’s brand, year, and price. We declare a generic function called “getProperty” that takes two arguments: “obj” of type T and “key” of type K, where K extends keyof T. The function returns the value corresponding to the given key in the object. We then create a car object and use the “getProperty” function to retrieve the car’s brand property and assign it to the “carBrand” variable. Finally, we log the value of “carBrand.
interfaceCar{
brand: string;
year: number;
price: number;}function getProperty<T,KextendskeyofT>(obj:T, key:K):T[K]{return obj[key];}const car: Car ={
brand:'Toyota',
year:2022,
price:25000,};const carBrand: string =getProperty(car,'brand');
console.log(carBrand);
On compiling, it will generate the following JavaScript code
functiongetProperty(obj, key){return obj[key];}var car ={
brand:'Toyota',
year:2022,
price:25000};var carBrand =getProperty(car,'brand');
console.log(carBrand);
Output
The above code will produce the following output
Toyota
Example 3: Mapping Object Properties
The keyof keyword is also useful for mapping properties from one object to another. In this example, we define an interface “Fruit” with properties representing the name and color of the fruit. We then create a new type, “FruitMapped” using the keyof within a mapped type. It maps each key in keyof Fruit to the type “string”. Finally, we create a “fruit” object using the FruitMapped type and log its value.
interfaceFruit{
name: string;
color: string;}
type FruitMapped ={[Kin keyof Fruit]: string;};const fruit: FruitMapped ={
name:'Apple',
color:'Red',};
console.log(fruit);
On compiling, it will generate the following JavaScript code
var fruit ={
name:'Apple',
color:'Red'};
console.log(fruit);
Output
The above code will produce the following output
{ name: 'Apple', color: 'Red' }
Example 4: Conditional Type Mapping
Another powerful application of the keyof keyword is in conditional type mapping. This allows us to selectively map properties based on certain conditions. In this example, we have an interface “Product” representing a product’s name, price, and availability. We define a type “DiscountedProducts” that utilizes conditional mapping using keyof. It checks if the property’s value extends the “number” type and maps it to the union type of the original value and “null”. For all other property types, it keeps the original value type unchanged. Finally, we create a “product” object using the DiscountedProducts type.
interfaceProduct{
name: string;
price: number;
inStock: boolean;}
type DiscountedProducts<T>={[Kin keyof T]:T[K]extendsnumber?T[K]|null:T[K];};const product: DiscountedProducts<Product>={
name:'Widget',
price:10,
inStock:true,};
console.log(product);
On compiling, it will generate the following JavaScript code
var product ={
name:'Widget',
price:10,
inStock:true};
console.log(product);
Output
The above code will produce the following output
{ name: 'Widget', price: 10, inStock: true }
Leave a Reply