Tutorial: Working with Dynamic Object Keys in TypeScript

Avatar

By squashlabs, Last Updated: May 7, 2024

Tutorial: Working with Dynamic Object Keys in TypeScript

Working with Dynamic Object Keys

Working with dynamic object keys in TypeScript allows developers to create more flexible and dynamic code. Instead of relying on static keys, which are predefined and cannot be changed at runtime, dynamic keys can be generated or modified dynamically based on certain conditions or user input.

In TypeScript, dynamic object keys can be useful in scenarios such as:

- Working with JSON data that has variable keys.

- Creating dynamic data structures.

- Accessing object properties dynamically.

- Validating and checking the type of object keys.

In this tutorial, we will explore various techniques and examples of working with dynamic object keys in TypeScript.

Related Article: How to Convert a String to a Number in TypeScript

Creating an Object with a Dynamic Key

To create an object with a dynamic key in TypeScript, you can use the bracket notation. This allows you to specify the key as a variable or an expression. Here's an example:

const dynamicKey = 'age';
const person = {
  name: 'John',
  [dynamicKey]: 25,
};

console.log(person); // { name: 'John', age: 25 }

In this example, we define a variable dynamicKey with the value 'age'. We then create an object person using the bracket notation to assign the value 25 to the age key. The resulting object will have the properties name and age.

Accessing Object's Property using Dynamic Key

To access an object's property using a dynamic key in TypeScript, you can also use the bracket notation. Here's an example:

const dynamicKey = 'age';
const person = {
  name: 'John',
  age: 25,
};

console.log(person[dynamicKey]); // 25

In this example, we define a variable dynamicKey with the value 'age'. We then access the age property of the person object using the bracket notation with the dynamicKey variable. The result will be 25.

Defining the Type of an Object Key

In TypeScript, you can define the type of an object key using the keyof keyword. This allows you to specify that a variable should be of a certain key of an object. Here's an example:

const person = {
  name: 'John',
  age: 25,
};

type PersonKey = keyof typeof person;

let key: PersonKey;
key = 'name'; // Valid
key = 'age'; // Valid
key = 'address'; // Error: Type '"address"' is not assignable to type 'PersonKey'

In this example, we define an object person with properties name and age. We then define a type PersonKey using the keyof keyword and the typeof operator to get the keys of the person object. We declare a variable key with the type PersonKey and assign different keys to it. TypeScript will enforce that the assigned values must be valid keys of the person object.

Related Article: How to Run Typescript Ts-Node in Databases

Inferring the Type of an Object Key

In TypeScript, the type of an object key can be inferred based on its usage. This allows you to write more concise code without explicitly specifying the type. Here's an example:

const person = {
  name: 'John',
  age: 25,
};

const key = 'name';
const value = person[key];

console.log(typeof value); // string

In this example, we have an object person with properties name and age. We define a variable key with the value 'name'. When we access the person object using the key variable, TypeScript infers that the type of the value variable is string, as the name property is of type string.

Checking the Type of an Object Key

To check the type of an object key in TypeScript, you can use the in operator. This allows you to determine whether a certain key exists in an object. Here's an example:

const person = {
  name: 'John',
  age: 25,
};

const key = 'name';

if (key in person) {
  console.log('Key exists in the person object');
} else {
  console.log('Key does not exist in the person object');
}

In this example, we have an object person with properties name and age. We define a variable key with the value 'name'. By using the in operator, we can check if the key exists in the person object. If it does, the code inside the if block will be executed; otherwise, the code inside the else block will be executed.

Validating Object Keys

In TypeScript, you can validate object keys using type guards and conditional statements. This allows you to ensure that only valid keys are used when accessing object properties dynamically. Here's an example:

const person = {
  name: 'John',
  age: 25,
};

function validateKey(key: string): key is keyof typeof person {
  return key in person;
}

function getProperty(key: string) {
  if (validateKey(key)) {
    return person[key];
  } else {
    throw new Error('Invalid key');
  }
}

console.log(getProperty('name')); // John
console.log(getProperty('address')); // Error: Invalid key

In this example, we have an object person with properties name and age. We define a function validateKey that takes a key parameter and checks if it exists in the person object. The key is keyof typeof person type guard is used to narrow down the type of the key parameter. We then define a function getProperty that takes a key parameter and uses the validateKey function to validate the key before accessing the person object. If the key is valid, the corresponding property value is returned; otherwise, an error is thrown.

Dynamic Keys in TypeScript and JavaScript

Dynamic keys are not specific to TypeScript and can also be used in JavaScript. However, TypeScript provides additional type checking and type inference capabilities, which can help catch potential errors and provide better developer experience.

In JavaScript, you can use the same techniques mentioned earlier to work with dynamic object keys. Here's an example:

const person = {
  name: 'John',
  age: 25,
};

const dynamicKey = 'age';

console.log(person[dynamicKey]); // 25

In this example, we have an object person with properties name and age. We define a variable dynamicKey with the value 'age'. By using the bracket notation, we can access the age property of the person object dynamically.

Related Article: Tutorial: Converting Boolean to String in TypeScript

Handling Non-Existent Keys in TypeScript

When working with dynamic object keys in TypeScript, it's important to handle cases where the key does not exist in the object. Otherwise, the code may throw a runtime error. One way to handle this is by using optional chaining and nullish coalescing operators.

Optional chaining (?.) allows you to safely access nested properties without throwing an error if a property along the chain is null or undefined. Nullish coalescing (??) allows you to provide a default value if the accessed property is null or undefined. Here's an example:

const person = {
  name: 'John',
  age: 25,
};

const key = 'address';

const address = person?.[key] ?? 'Unknown';

console.log(address); // Unknown

In this example, we have an object person with properties name and age. We define a variable key with the value 'address'. By using optional chaining (?.) and nullish coalescing (??), we can safely access the address property of the person object. If the address property is null or undefined, the default value 'Unknown' will be used instead.

Changing the Type of an Object Key

In TypeScript, it's possible to change the type of an object key by using mapped types. Mapped types allow you to transform the keys of an object type into a different type. Here's an example:

type Person = {
  name: string;
  age: number;
};

type KeyToUpperCase = {
  [K in keyof T as Uppercase]: T[K];
};

const person: KeyToUpperCase = {
  NAME: 'John',
  AGE: 25,
};

console.log(person); // { NAME: 'John', AGE: 25 }

In this example, we have a type Person with properties name and age. We define a mapped type KeyToUpperCase that transforms the keys of the Person type to uppercase using the Uppercase utility type. We then declare a variable person with the KeyToUpperCase type and assign values to the transformed keys (NAME and AGE).

Case-Sensitivity of Object Keys in TypeScript

In TypeScript, object keys are case-sensitive. This means that name and Name are considered as different keys. Here's an example:

const person = {
  name: 'John',
};

console.log(person.name); // John
console.log(person.Name); // undefined

In this example, we have an object person with a property name. When we access the name property using the correct case (person.name), we get the value 'John'. However, when we use a different case (person.Name), we get undefined because it is treated as a different key.

External Sources

- TypeScript Documentation: Indexable Types

- TypeScript Deep Dive: Index Signatures

- MDN Web Docs: Property accessors

You May Also Like

Tutorial: Navigating the TypeScript Exit Process

Navigating the TypeScript exit process can be challenging for software engineers. This tutorial provides a guide on returning a value, defining an ex… read more

How to Work with Dynamic Objects in TypeScript

Manipulating dynamic objects in TypeScript can be a complex task, but with this step-by-step guide, you'll learn how to work with them efficiently. F… read more

Tutorial on Prisma Enum with TypeScript

Prisma Enum is a powerful feature in TypeScript that allows you to define and use enumerated types in your Prisma models. This tutorial will guide yo… read more

Tutorial: Checking Enum Value Existence in TypeScript

Checking enum value existence in TypeScript is a crucial task for developers. This tutorial provides a step-by-step guide on how to efficiently check… read more

How to Implement ETL Processes with TypeScript

This article provides a comprehensive guide on creating ETL processes using TypeScript. It covers the purpose of TypeScript in ETL, the benefits of u… read more

Working with HTML Button Elements in TypeScript

This tutorial provides a comprehensive guide on working with HTML button elements in TypeScript. From creating and styling buttons to adding event li… read more

Tutorial: Extending the Window Object in TypeScript

Extending the window object in TypeScript is a powerful technique that allows you to add custom properties and methods to the global scope of your we… read more

Tutorial: Readonly vs Const in TypeScript

A detailed comparison of Readonly and Const in TypeScript. This article explores the Readonly and Const keywords in TypeScript, highlighting their di… read more

How to Update Variables & Properties in TypeScript

Updating variables and properties in TypeScript can be a simple and process. This step-by-step tutorial will guide you through the correct usage of t… read more

How to Use the Record Type in TypeScript

A basic guide on using the Record type in TypeScript, and its application. Chapters include Basic Usage, Readonly Record, Advanced Usage, and Best Pr… read more