score:1

Accepted answer

First of all, there isn't a nice way to do this and it's still in discussion: https://github.com/Microsoft/TypeScript/issues/3500

Below are 2 potential ways to solve your issue.

  1. Declare the key outside of the loop:
const formElementsArray: { id: string; config: Config }[] = [];
let key: keyof typeof this.state.controls;
for (key in this.state.controls) {
  formElementsArray.push({
    id: key,
    config: this.state.controls[key],
  });
}
  1. Use Object.keys & cast the key to the desired type:
const formElementsArray: { id: string; config: Config }[] = (Object.keys(
  this.state.controls
) as (keyof typeof this.state.controls)[]).map((key) => ({
  id: key,
  config: this.state.controls[key],
}));

You could also make it clearer by using an enum for the control key

enum ControlKey {
  email = "email",
  password = "password",
}

interface SignInFormState {
  controls: {
    [key in ControlKey]: Config;
  };
  isSignUp: boolean;
  [key: string]: boolean | Object | Config;
}

then

1b.

const formElementsArray: { id: string; config: Config }[] = [];
let key: ControlKey;
for (key in this.state.controls) {
  formElementsArray.push({
    id: key,
    config: this.state.controls[key],
  });
}

or

2b.

const formElementsArray: { id: string; config: Config }[] = (Object.keys(
  this.state.controls
) as ControlKey[]).map((key) => ({
  id: key,
  config: this.state.controls[key],
}));

Hope this helps


Related Query

More Query from same tag