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 Update Variables & Properties 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: Fixing 'TypeScript Does Not Exist on Type Never' Errors

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.

Related Article: Tutorial: Date Comparison in TypeScript

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.

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).

Related Article: How to Check if a String is in Enum in TypeScript: A Tutorial

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

How to Convert Strings to Booleans in TypeScript

A technical guide on converting strings to booleans in TypeScript. Explore various methods, including using the Boolean() function, the === operator, if-else statements,... 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 using TypeScript, and... read more

Building a Rules Engine with TypeScript

Building a rules engine with TypeScript is a detailed guide that teaches you how to construct a powerful rules engine using TypeScript. The article covers various topics... 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. From creating dynamic... read more

How to Verify if a Value is in Enum in TypeScript

This article provides a guide on how to check if a specific value exists in an Enum using TypeScript. It covers understanding Enums in TypeScript, validating Enum... read more

How Static Typing Works in TypeScript

TypeScript is a powerful programming language that offers static typing capabilities for better code quality. In this comprehensive guide, we will explore various... read more