How to dynamically assign properties to an object in TypeScript
Tags: typescript, webdev
Published: 2022-09-13 14:56:54

**Written by [Ohans Emmanuel](https://blog.logrocket.com/author/ohansemmanuel/)✏️**

## Introduction

Consider the following example:

```typescript
const organization = {}
organization.name = "Logrocket"                                                                                 
```

This seemingly harmless piece of code throws a TypeScript error on dynamically assigning `name` to the `organization` object. ![An error is thrown when dynamically assigning a property to an object](https://blog.logrocket.com/wp-content/uploads/2022/09/error-thrown-dynamically-assigning-property-object.png) 

See this example in [the TypeScript Playground](https://www.typescriptlang.org/play#code/MYewdgzgLgBCBOBzAhmAlgL2VN4YF4YBvAXwCgyEV0sdwA6MZAWwFMCYAiAGREXhDAA1qyicKMSVOkzZc+QsVLlK1WukUgA). 

The source of confusion, which is perhaps rightly justified if you’re a TypeScript beginner, is: how could something that seems so simple be such a problem in TypeScript? 

The TL;DR of it all is that, if you cannot define the variable type at declaration time, you can use the `Record` utility type or an object index signature to solve this. But in this post, we’ll go through the problem itself and work toward a solution that should work in most cases. 

_Jump ahead:_

*   [Understanding the problem with dynamically assigning properties to objects](#understanding-problem-dynamically-assigning-properties-objects)
*   [Resolving the problem](#resolving-problem)
    *   [Solution 1: Explicitly type the object at declaration time](#solution-1-explicitly-type-object-declaration-time)
    *   [Solution 2: Use an object index signature](#solution-2-use-object-index-signature)
    *   [Solution 3: Use the `Record` utility type](#solution-3-use-record-utility-type)

## Understanding the problem with dynamically assigning properties to objects <a name="understanding-problem-dynamically-assigning-properties-objects">

Generally speaking, TypeScript determines the type of a variable when it is declared, and this determined type doesn’t change, i.e., it stays the same all through your application. 

There are exceptions to this rule, such as when considering type narrowing or working with the `any` type, but this is a general rule to remember otherwise. 

In the earlier example, the `organization` object is declared as follows:

```typescript
const organization = {}
```

There is no explicit type assigned to the `organization` variable, so TypeScript infers a type of `organization` based on the declaration to be `{}`, i.e., the literal empty object. 

For example, if you add a type alias, you can explore the type of `organization`:

```typescript
type Org = typeof organization
```

![Exploring the literal object type](https://blog.logrocket.com/wp-content/uploads/2022/09/exploring-literal-object-type.png) 

See this in [the TypeScript Playground](https://www.typescriptlang.org/play?#code/MYewdgzgLgBCBOBzAhmAlgL2VN4YF4YBvAXwCgyoBPABwFMYB5JAma+kAMziVU21xgKCFOiw5wAOjDIAtg0IAiADIhE8EMADWdKIooxDR4ydNnzFy1es3bd4xSA). 

When you then try to reference the `name` prop on this empty object literal:

```typescript
organization.name = ...
```

TypeScript yells.

> Property 'name' does not exist on type ‘ `{}`‘

When you understand the issue, the error does seem appropriate. 

Let’s fix this.

## Resolving the problem <a name="resolving-problem">

There are numerous ways you can resolve the TypeScript error here. Let’s consider these:

### Solution 1: Explicitly type the object at declaration time <a name="solution-1-explicitly-type-object-declaration-time">

This is the easiest solution to reason through. At the time you declare the object, go ahead and type it. Furthermore, assign it all the relevant values.

```typescript
type Org = {
    name: string
}

const organization: Org = {
    name: "Logrocket"
}
```

See this in [the TypeScript Playground](https://www.typescriptlang.org/play?#code/FAFwngDgpgBA8gJwOYwLwwN7BjmA7AQwFsoAuGAZxAQEs8lgBfYYAYwHs8qZ3kC8aALwIgancohTosufMTIwARABl2SBO1YBrKCEVMgA). 

This eliminates any surprises. You’re clearly stating what this object type is and rightly declaring all relevant properties when you create the object. 

However, this is not always feasible if the object properties must be added _dynamically_, which is why we’re all here.

### Solution 2: Use an object index signature <a name="solution-2-use-object-index-signature">

Occasionally, the properties of the object truly need to be added at a time after they’ve been declared. In this case, you can use the object index signature, as follows:

```typescript
type Org = {[key: string] : string}
const organization: Org = {}
organization.name = "Logrocket"
```

See this in [the TypeScript Playground](https://www.typescriptlang.org/play#code/FAFwngDgpgBA8gJwOYwLwwN4G0DWUwBcMAziAgJYB2SAujEaRdQL7DADGA9paTJ8gENK5AF4CQ5bkUQp0GVsH5Iho8ZMoA6SgIC2sdACIAMpyQJO7PCAPAgA). 

At the time the `organization` variable is declared, you can go ahead and explicitly type it to the following `{[key: string] : string}`. 

To explain the syntax further, you might be used to object types having fixed property types:

```typescript
type obj = {
  name: string
}
```

However, you can also substitute `name` for a “variable type”. 

For example, if you want to define any string property on `obj`:

```typescript
type obj = {
 [key: string]: string
}
```

Note that the syntax is similar to how you’d use a variable object property in standard JavaScript:

```typescript
const variable = "name" 
const obj = {
   [variable]: "Freecodecamp"
}
```

The TypeScript equivalent is called an object index signature. Moreover, note that you could type `key` with other primitives:

```typescript
// number 
type Org = {[key: number] : string}

// string 
type Org = {[key: string] : string}

//boolean
type Org = {[key: boolean] : string}
```

### Solution 3: Use the `Record` utility type <a name="solution-3-use-record-utility-type">

The [`Record` utility type](https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type) allows you to constrict an object type whose properties are `Keys` and property values are `Type`. It has the following signature: `Record<Keys, Type>`. 

In our example, `Keys` represents `string` and `Type`, `string` as well. The solution here is quite concise as shown below:

```typescript
type Org = Record<string, string>

const organization: Org = {}

organization.name = "Logrocket"
```

Instead of using a type alias, you can also inline the type:

```typescript
const organization: Record<string, string> = {}
```

![Using the Record utility type](https://blog.logrocket.com/wp-content/uploads/2022/09/using-record-utility-type.png)

See this in [the TypeScript Playground](https://www.typescriptlang.org/play?#code/FAFwngDgpgBA8gJwOYwLwwEpQMYHsEAmAPAM4gICWAdkgDQxmU0B8wweVZM+SAhlRQBevEBVxUAXPGRoYAbwC+bHvyEixVAHRVeAW1joARABlcSBLmwBrKCENA).

## Conclusion

Apart from primitives, the most common types you’ll have to deal with are likely object types. 

In cases where you need to build an object dynamically, take advantage of the `Record` utility type or use the object index signature to define the allowed properties on the object. 

If you’d like to read more on this subject, feel free to [check out my cheatsheet](https://www.ohansemmanuel.com/cheatsheet/top-7-stack-overflowed-typescript-questions) on the seven most-asked TypeScript questions on Stack Overflow, or [tweet me any questions](https://twitter.com/ohansemmanuel?lang=en). Cheers!

---
## [LogRocket](https://lp.logrocket.com/blg/signup) proactively surfaces and diagnoses the most important issues in your TypeScript apps

[![Diagnose Issues In Your TypeScript Apps](https://blog.logrocket.com/wp-content/uploads/2017/03/1d0cd-1s_rmyo6nbrasp-xtvbaxfg.png)](https://lp.logrocket.com/blg/signup)

Thousands of engineering and product teams use [LogRocket](https://lp.logrocket.com/blg/signup) to reduce the time it takes to understand the root cause of technical and usability issues in their TypeScript apps. With LogRocket, you'll spend less time on back-and-forth conversations with customers and remove the endless troubleshooting process. LogRocket allows you to spend more time building new things and less time fixing bugs.

Proactively fix your TypeScript apps — try [LogRocket](https://lp.logrocket.com/blg/signup) today.