![TypeScript Tutorial](/typescript/images/typescript-mini-logo.jpg)
- TypeScript Basics
- TypeScript - Home
- TypeScript - Overview
- TypeScript - Environment Setup
- TypeScript - Basic Syntax
- TypeScript vs. JavaScript
- TypeScript - Features
- TypeScript - Variables
- TypeScript - let & const
- TypeScript - Operators
- TypeScript Basic Types
- TypeScript - Types
- TypeScript - Type Annotations
- TypeScript - Type Inference
- TypeScript - Numbers
- TypeScript - Strings
- TypeScript - Boolean
- TypeScript - Arrays
- TypeScript - Tuples
- TypeScript - Enums
- TypeScript - Any
- TypeScript - Never
- TypeScript - Union
- TypeScript - Literal Types
- TypeScript - Symbols
- TypeScript - null vs. undefined
- TypeScript - Type Aliases
- TypeScript Control Flow
- TypeScript - Decision Making
- TypeScript - If Statement
- TypeScript - If Else Statement
- TypeScript - Nested If Statements
- TypeScript - Switch Statement
- TypeScript - Loops
- TypeScript - For Loop
- TypeScript - While Loop
- TypeScript - Do While Loop
- TypeScript Functions
- TypeScript - Functions
- TypeScript - Function Types
- TypeScript - Optional Parameters
- TypeScript - Default Parameters
- TypeScript - Anonymous Functions
- TypeScript - Function Constructor
- TypeScript - Rest Parameter
- TypeScript - Parameter Destructuring
- TypeScript - Arrow Functions
- TypeScript Interfaces
- TypeScript - Interfaces
- TypeScript - Extending Interfaces
- TypeScript Classes and Objects
- TypeScript - Classes
- TypeScript - Objects
- TypeScript - Access Modifiers
- TypeScript - Readonly Properties
- TypeScript - Inheritance
- TypeScript - Static Methods and Properties
- TypeScript - Abstract Classes
- TypeScript - Accessors
- TypeScript - Duck-Typing
- TypeScript Advanced Types
- TypeScript - Intersection Types
- TypeScript - Type Guards
- TypeScript - Type Assertions
- TypeScript Type Manipulation
- TypeScript - Creating Types from Types
- TypeScript - Keyof Type Operator
- TypeScript - Typeof Type Operator
- TypeScript - Indexed Access Types
- TypeScript - Conditional Types
- TypeScript - Mapped Types
- TypeScript - Template Literal Types
- TypeScript Generics
- TypeScript - Generics
- TypeScript - Generic Constraints
- TypeScript - Generic Interfaces
- TypeScript - Generic Classes
- TypeScript Miscellaneous
- TypeScript - Triple-Slash Directives
- TypeScript - Namespaces
- TypeScript - Modules
- TypeScript - Ambients
- TypeScript - Decorators
- TypeScript - Type Compatibility
- TypeScript - Date Object
- TypeScript - Iterators and Generators
- TypeScript - Mixins
- TypeScript - Utility Types
- TypeScript - Boxing and Unboxing
- TypeScript - tsconfig.json
- From JavaScript To TypeScript
- TypeScript Useful Resources
- TypeScript - Quick Guide
- TypeScript - Useful Resources
- TypeScript - Discussion
TypeScript - Keyof Type Operator
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.
interface Person { 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”.
interface Car { brand: string; year: number; price: number; } function getProperty<T, K extends keyof T>(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 −
function getProperty(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.
interface Fruit { name: string; color: string; } type FruitMapped = { [K in 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.
interface Product { name: string; price: number; inStock: boolean; } type DiscountedProducts<T> = { [K in keyof T]: T[K] extends number ? 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 }