Beginner's TypeScript #11
Tags: programming, beginners, typescript
Published: 2023-12-30 15:00:00

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bnze5wrwcw41umm3ekl1.png)

⭐ **Assigning Dynamic Keys to an Object** ⭐

Consider this **createCache** function:

```ts
const createCache = () => {
  const cache = {};

  const add = (id: string, value: string) => {
    cache[id] = value;
  };

  const remove = (id: string) => {
    delete cache[id];
  };

  return {
    cache,
    add,
    remove,
  };
};
```

We have an empty object that we are calling **cache**, and we are allowing users to specify add and remove on it.

There are errors in the **createCache** function:

```bash
Expression of type 'string' can't be used to index type '{}'
```

There is no indexing happening with our current code..

We will figure out how to reference the TypeScript docs and determine what could be causing this problem.

Update **cache** to be typed properly so the errors go away.

🌟 **Solutions:**

1️⃣ **Use the Record Utility Type:**

One solution is to type **cache** as a **Record**:

```ts
const cache: Record<string, string> = {}
```

The first type argument to **Record** is for the **key**, and the second is for the **value**. In our case, both are strings.

The Record type allows us to add any number of dynamic keys to the object at runtime, using something like this:

```ts
cache['keyHere'] = 'valueHere'
```

**Record** is different than the Set and Map we looked at earlier– it is only at the type level.

2️⃣ **Use an Index Signature:**

Here is another way to update **cache** to please TypeScript:

Recall that in the "before" code, we had lots of errors like "You can't use that to index this."

These errors were saying that they could not tell what types the key was. Whenever you see an error about an index, it is usually about an object key!

For this fix, we will add what is called an index signature to our cache:

```ts
const cache: {
  [id: string]: string;
} = {}
```

Index signatures put the name of the index and its type (string or number) inside of square brackets.

So from the above, we can see that **id** is the index for **cache**.

If we were to set it to **[id: number]: string**, every time we called **cache.add()**, we would have to pass a number as the first argument.

3️⃣ **Use an Interface with an Index Signature:**

We can also create an interface for Cache that contains the index signature:

```ts
interface Cache {
  [id: string]: string;
}
```

Then inside of the **createCache** function we would type cache as Cache:

```ts
const createCache = () => {
  const cache: Cache = {};
```

This would work with a type instead of interface as well.

**Which One to Use?** 🧐

All of these solutions are fine-- there are no pros or cons between them.

Assigning dynamic keys to an object is a common pattern in JavaScript, and these techniques allow you to do it.

---

I hope you found it useful. Thanks for reading. 🙏

Let's get connected! You can find me on:
- **Medium:** https://medium.com/@nhannguyendevjs/
- **Dev**: https://dev.to/nhannguyendevjs/
- **Hashnode**: [https://nhannguyen.hashnode.dev](https://nhannguyen.hashnode.dev/)/
- **Linkedin:** https://www.linkedin.com/in/nhannguyendevjs/
- **X (formerly Twitter)**: https://twitter.com/nhannguyendevjs/