Replace

[field: string]: {
   property1: string,
   property2: string
}

by

    interface Anything {
      [key: string]: any;
    }

And when you're calling then: do this

let item = { property1: "randomTest", property2: "randomTest1", property3: "randomTest3"}

 this.setState({
    [item].property1: "test value 1"
 })
Answer from mdev on Stack Overflow
🌐
Medium
medium.com › @jofaval › objecy-with-dynamic-keys-in-typescript-468c358a5f8b
Objects with Dynamic Keys in TypeScript | by Pepe Fabra Valverde | Medium
October 20, 2023 - A short little article about TypeScript’s inference system and how we can pre-define custom keys, dynamically · This may have duplicates, there may be articles already written about this. But, at the time when I needed this, I was not able to find something similar, not quite what I had in mind. const useVisible = <TName extends string>(name: TName) => { const [visible, setVisibility] = useState(false); const capitalized = (name.charAt(0).toLocaleUpperCase() + name.substring(1)) as Capitalize<TName>; type TCap = typeof capitalized; type VisibleReturn = { [k in `close${TCap}`]: () => void; } & { [k in `is${TCap}Visible`]: boolean; } & { [k in `open${TCap}`]: () => void; }; return { [`close${capitalized}`]: () => setVisibility(false), [`is${capitalized}Visible`]: visible, [`open${capitalized}`]: () => setVisibility(true), } as { [k in keyof VisibleReturn]: VisibleReturn[k]; }; };
Discussions

reactjs - Dynamic object key with Typescript in React event handler - Stack Overflow
Similar but distinct from How do I dynamically assign properties to an object in TypeScript? I have a component with the state type: { low: string high: string } And as is a common pattern in... More on stackoverflow.com
🌐 stackoverflow.com
September 19, 2017
reactjs - Pick<S, K> type with dynamic/computed keys - Stack Overflow
The latest @types/react (v15.0.6) make use of features added in TypeScript 2.1 for setState, namely Pick . Which is a good thing, because now the typings are correct, because before the ... More on stackoverflow.com
🌐 stackoverflow.com
reactjs - React + TypeScript set state with dynamic key names - Stack Overflow
To validate a Stripe checkout form, I'm trying to dynamically store the change events from the form in state. The event contains elementType which is either 'cardNumber', 'cardExpiry', or 'cardCvc'... More on stackoverflow.com
🌐 stackoverflow.com
October 13, 2019
Dynamic object keys in TypeScript
I have a problem when setting the type of a dynamic object in TypeScript because the object that i create has dynamic keys and three that are not. Here’s how i defined the type for the object: interface GraphReturns { … More on forum.freecodecamp.org
🌐 forum.freecodecamp.org
2
0
June 10, 2022
Top answer
1 of 3
11

So after doing more research I can provide a little more context on what is happening in the above code.

When you do something like const name = 'Bob' the type of the variable name is 'Bob' not string. However, if you replace the const with a let (let name = 'Bob') the variable name will be of type string.

This concept is called "widening". Basically, it means that the type system tries to be as explicit as possible. Because const can not be reassigned TypeScript can infer the exact type. let statements can be reassigned. Thus, TypeScript will infer string (in the above example) as the type of name.

The same is happening with const key = e.currentTarget.name as keyof Person. key will be of (union) type "name"|"age", which is exactly what we want it to be. But in the expression this.setState({ [key]: value }); variable key is (incorrectly) widened to a string.


tl;dr; It seems like there is a bug in TypeScript. I posted the issue to the Github repo and the TypeScript team is investigating the problem. :)

As a temporary workaround you can do:

this.setState({ [key as any]: value });
2 of 3
3

The answer from Sebastian no longer works for me (though at one stage it did). I now do the following until it is resolved in Typescript core (as per the issue listed in Sebastians answer):

  handleUpdate (e:React.SyntheticEvent<HTMLInputElement>) {
    const newState = {};
    newState[e.currentTarget.name] = e.currentTarget.value;
    this.setState(newState);
  }

It's lame, but it works

🌐
Medium
medium.com › @vincentnewkirk › typing-dynamic-object-keys-with-ts-de0d5990a58e
Typing Dynamic Object Keys With TS | by Vincent Newkirk | Medium
February 12, 2019 - const updateValue: <T extends keyof State, K extends State[T]> = (name: T, value: K): void => this.setState({ [name]: value }); Using the generic with these keywords,T extends keyof State , tells TS that T should be one of the keys of the State interface (id, name, etc…). Then the K extends State[T] let’s typescript know that K ‘s type should equal that of State[T] (this is simply bracket notation).
🌐
Stack Overflow
stackoverflow.com › questions › 58356706 › react-typescript-set-state-with-dynamic-key-names
reactjs - React + TypeScript set state with dynamic key names - Stack Overflow
October 13, 2019 - I want to handle this using dynamic key assignment in a one liner. Here's my working update with the desired line commented out: public handleChange(e: stripe.elements.ElementChangeResponse) { // todo: git gud // should be able to figure out typescript so this line works: // this.setState({[e.elementType + 'Event']: e}); switch (e.elementType) { case 'cardCvc': { this.setState({cardCvcEvent: e}); break; } case 'cardExpiry': { this.setState({cardExpiryEvent: e}); break; } case 'cardNumber': { this.setState({cardNumberEvent: e}); break; } } }
Find elsewhere
🌐
freeCodeCamp
forum.freecodecamp.org › t › dynamic-object-keys-in-typescript › 516302
Dynamic object keys in TypeScript - The freeCodeCamp Forum
June 10, 2022 - I have a problem when setting the type of a dynamic object in TypeScript because the object that i create has dynamic keys and three that are not. Here’s how i defined the type for the object: interface GraphReturns { [key: string]: { '%': number, value: number, '�umulated': number }, total: number, 'total_%': number, date: string } The errors i get: Property ‘total’ of type ‘number’ is not assignable to ‘string’ index type ‘{ ‘%’: number; value: number; ‘�umu...
🌐
GitHub
github.com › DefinitelyTyped › DefinitelyTyped › issues › 26635
[@types/react] cannot setState with dynamic key name type-safe · Issue #26635 · DefinitelyTyped/DefinitelyTyped
June 18, 2018 - I cannot call setState with an object being created from computed property name with type-safety: type State = { username: string, password: string }; type StateKeys = keyof State; class A extends React.Component<{}, State> { dynSetState(key: StateKeys, value: string) { this.setState({ [key]: value // Error here. Pretty sure key is in StateKeys }); } } I do aware of #18365, and the workaround in #18365 (comment) . However, when using the workaround, Typescript doesn't error out when it should: dynLooselySetState(key: string, value: string) { this.setState(prevState => ({ ...prevState, [key]: value // No error here, but can't ensure that key is in StateKeys })); } 👍React with 👍64rohanray, jardakotesovec, NachoJusticia, MigCoder, leefernandes and 59 more ·
Author: DefinitelyTyped
🌐
Omarileon
omarileon.me › blog › typescript-dynamic-object-keys
mari. | How to Create Objects with Dynamic Keys in TypeScript
April 15, 2024 - TypeScript provides a utility type exactly for the purpose of defining dynamic objects, the Record type. It looks like this: ... It’s generic, and takes two type parameters – one for whatever type your keys might be, and one for whatever type your values might be.
Top answer
1 of 16
1174

Index signatures

It is possible to denote obj as any, but that defeats the whole purpose of using typescript. obj = {} implies obj is an Object. Marking it as any makes no sense. To accomplish the desired consistency an interface could be defined as follows, using an index signature

interface LooseObject {
    [key: string]: any
}

var obj: LooseObject = {};

OR to make it compact:

var obj: {[k: string]: any} = {};

LooseObject can accept fields with any string as key and any type as value.

obj.prop = "value";
obj.prop2 = 88;

The real elegance of this solution is that you can include typesafe fields in the interface.

interface MyType {
    typesafeProp1?: number,
    requiredProp1: string,
    [key: string]: any
}

var obj: MyType ;
obj = { requiredProp1: "foo"}; // valid
obj = {} // error. 'requiredProp1' is missing
obj.typesafeProp1 = "bar" // error. typesafeProp1 should be a number

obj.prop = "value";
obj.prop2 = 88;

Record<Keys,Type> utility type

Update (August 2020): @transang brought up the Record<Keys,Type> utility type in comments

Record<Keys,Type> is a Utility type in typescript. It is a much cleaner alternative for key-value pairs where property-names are not known. It's worth noting that Record<Keys,Type> is a named alias to {[k: Keys]: Type} where Keys and Type are generics. IMO, this makes it worth mentioning here

For comparison,

var obj: {[k: string]: any} = {};

becomes

var obj: Record<string,any> = {}

MyType can now be defined by extending Record type

interface MyType extends Record<string,any> {
    typesafeProp1?: number,
    requiredProp1: string,
}

While this answers the Original question, the answer here by @GreeneCreations might give another perspective on how to approach the problem.

2 of 16
120

This solution is useful when your object has Specific Type. Like when obtaining the object to other source.

let user: User = new User();
(user as any).otherProperty = 'hello';
//user did not lose its type here.
🌐
Reddit
reddit.com › r/typescript › react state - setting state dynamically
r/typescript on Reddit: React State - Setting state dynamically
February 4, 2019 -

Hi guys,

I'm trying to set a React component's state dynamically basically off an input element. The type-checker is not working as I'd thought. I'm getting error: Missing property from type Pick<State, "person" | "anotherStateVar">

Could someone advise how I should be doing this? I don't want to cast as any, or State - as this defeats the whole purpose of type-checking. Is there something obvious I'm missing?

      type State = {
        person: string,
        anotherStateVar: string,
      }

      handleChange = async (event: React.FormEvent<HTMLInputElement>) => {
        const {name, value} = event.currentTarget
        try {
          await externalServiceCall()
          //setting state dynamically + have ability to set another key if I choose
          this.setState({[name]: {value}})
          //this.setState({[name]: {value}, anotherStateVar: 'hello'})
        } catch (e) {
          //error things
        }
      }

edit: formatting

🌐
How to
sharooq.com › how-to-use-dynamic-keys-with-typescript-objects
How to - use dynamic keys with TypeScript objects - Sharooq
April 18, 2023 - By using index signatures, the Record utility type, mapped types, and nested types, you can define and manipulate objects with dynamic keys efficiently and safely.
🌐
Bobby Hadz
bobbyhadz.com › blog › react-usestate-dynamic-key
Set and Access state using a Dynamic key in React | bobbyhadz
April 6, 2024 - Copied!import {useState} from 'react'; const App = () => { const [employee, setEmployee] = useState({id: 1, name: 'Alice', salary: 100}); const key = 'salary'; // ✅ Access state using dynamic key console.log(employee[key]); // 👉️ 100 const handleClick = () => { // ✅ Set state using dynamic key setEmployee({...employee, [key]: employee.salary + 100}); }; return ( <div> <button onClick={handleClick}>Increase salary</button> <h2>id: {employee.id}</h2> <h2>name: {employee.name}</h2> <h2>salary: {employee.salary}</h2> </div> ); }; export default App;
🌐
Squash
squash.io › tutorial-working-with-dynamic-object-keys-in-typescript
Tutorial: Working with Dynamic Object Keys in TypeScript
May 7, 2024 - Related Article: How to Convert a String to a Number in TypeScript · 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.
🌐
Reddit
reddit.com › r/react › typescript & react -- dynamic object types
r/react on Reddit: Typescript & React -- Dynamic Object Types
April 24, 2023 -

Hello friends,

I am working on an application that will require dynamic typing of an object. The user should be able to define a certain list of attributes they want to track. The list of attributes they create for their tracking will be stored in the back-end Mongo DB. Basically each user should have an "attributes" object that extends the default object with whatever additional key:value pairs they want to track.

I'm curious how this is possible when using Typescript, since it seems to want everything to be pre-defined.

Here is an example of the current statically-typed object:

export interface IDay {
id: number;
dayRating?: number | undefined;
sleep?: number | undefined;
date?: string | undefined;
notes?: string | undefined;
}