Hi, I'm Mayone 👋

I'm a Web Developer and Entrepreneur

Tejiri Mayone

Hi, I'm Mayone 👋

I'm a Web Developer and Entrepreneur

Flexible Data Structures in TypeScript: Working with Arrays of Dynamic Objects

5 minutes
August 23, 2025
Flexible Data Structures in TypeScript:

Flexible Data Structures in TypeScript:

Introduction

When building applications, you often need to handle data with flexible structures—think country codes, user metadata, or API responses with dynamic keys. In TypeScript, one way to achieve this is by using an array of objects with an index signature, like this:

countryCode: { [key: string]: string }[] = [];

In this post, we’ll explore what this code does, why it’s useful, and how to modify it for different scenarios. Whether you’re a beginner or an intermediate developer, you’ll learn how to leverage this powerful TypeScript feature in your projects.

What Does the Code Mean?

Let’s break down the snippet:

For example, you could store country data like this:

countryCode.push({
  name: "United States",
  code: "US",
  dialCode: "+1"
});

This flexibility makes it ideal for scenarios where the exact property names might vary or come from an external source, like an API.

Why Use This Structure? This structure shines in cases like:

Example: Using the countryCode Array Here’s how you might use this in a real application:

let countryCode: { [key: string]: string }[] = [];

countryCode.push({
  name: "Canada",
  code: "CA",
  dialCode: "+1"
});
countryCode.push({
  country: "Japan",
  isoCode: "JP",
  phonePrefix: "+81"
});

console.log(countryCode[0].name); // Output: "Canada"
console.log(countryCode[1].isoCode); // Output: "JP"

Notice how the objects can have different keys (name vs. country, code VS. isoCode ) but still conform to the type because all values are strings.

Modifying the Code for Different Use Cases The beauty of this structure is its flexibility, but you can modify it to suit specific needs. Here are a few variations:

  1. llowing Mixed Value Types If you need to store numbers (e.g., population) alongside strings, you can adjust the index signature:
let countryCode: { [key: string]: string | number }[] = [];

countryCode.push({
  name: "Brazil",
  code: "BR",
  population: 213000000 // Number is now allowed
});

This allows values to be either strings or numbers, making the structure more versatile.

  1. Using a Specific Interface for Strict Typing If you want to enforce specific properties (e.g., every object must have name and code ), use an interface:
interface Country {
  name: string;
  code: string;
  dialCode?: string; // Optional property
}

let countryCode: Country[] = [];

countryCode.push({
  name: "Germany",
  code: "DE",
  dialCode: "+49"
});

This is stricter and ensures consistency, but it’s less flexible than the index signature.

  1. Adding Methods to Work with the Data You can extend the code by adding functions to manipulate the array. For example, a function to find a country by code:
let countryCode: { [key: string]: string }[] = [
  { name: "India", code: "IN", dialCode: "+91" },
  { name: "Australia", code: "AU", dialCode: "+61" }
];

function findCountryByCode(code: string) {
  return countryCode.find(country => country.code === code);
}

console.log(findCountryByCode("IN")); // Output: { name: "India", code: "IN", dialCode: "+91" }

This makes the data structure more practical for real-world applications.

Common Pitfalls to Avoid

countryCode.push({
  name: "France",
  code: "FR",
  population: 67000000 // Error: Type 'number' is not assignable to type 'string'
});

Fix it by converting numbers to strings or updating the type signature.

Real-World Application Imagine you’re building a dropdown for selecting countries in a form. You fetch country data from an API, which returns an array of objects with varying keys (e.g.,name, code, dial_code or country_code). The { [key: string]: string }[] type ensures you can handle this data safely while maintaining type checking. You could then map the array to display options in your UI:

countryCode.forEach(country => {
  console.log(`<option value="${country.code}">${country.name}</option>`);
});

Conclusion

The countryCode: { [key: string]: string }[] = []; declaration in TypeScript is a powerful way to define an array of objects with flexible, string-based key-value pairs. It’s perfect for dynamic data like country codes or API responses. By understanding its structure and how to modify it—whether by allowing mixed types, using strict interfaces, or adding helper methods—you can adapt it to a wide range of use cases. Try experimenting with this in your next TypeScript project, and let us know in the comments how you’ve used dynamic objects in your applications!

Call to Action Have you used index signatures in TypeScript before? Share your examples or questions in the comments below! If you found this post helpful, subscribe for more TypeScript tips and tricks.