Skip to content

[Feature request] Support for type checking properties in an object with different types #23927

Closed
@Albert-Gao

Description

@Albert-Gao

I got an object like this:

const state = {
      isFormOK: true,
      fieldA: {
          value: 'abc';
          status: 'ok' | 'normal' | 'error';
          errorText: '';
      }
}

There could be many fields which have the same structure as the above fieldA property, and in the code, I will actually use index property to access them because they are random. So I declared types like this:

export interface FieldState {
  value: string;
  status: 'ok' | 'normal' | 'error';
  errorText: string;
}

export interface ComponentState {
  isFormOK: boolean;
  [fieldName: string]: FieldState
}

If you just swap those interface with type, then it works for flow.js. Whereas can't do that in Typescript, because as the doc said:

While string index signatures are a powerful way to describe the “dictionary” pattern, they also enforce that all properties match their return type. This is because a string index declares that obj.property is also available as obj["property"].

And the error is:

Property isFormOK of type boolean is not assignable to string index type FieldState

I think it's fine, because when I access the state using an index, I might go to the case where the index equals isFormOK but I still want to use it like a FieldState. I know. But how could I solve it and type check this object?

Currently, we have 2 options:

  1. Tried changing [fieldName: string]: FieldState to [fieldName: string]: {}, then cast it to FieldState everytime when use it. it works. But then the type for state doesn't convey the message where the real structure of this object.

  2. Tried changing ComponentState to

export type ComponentState =
    { isFormOK: boolean } &
    { [fieldName: string]: FieldState }

I currently use the 2nd approach.

What about just something like:

export interface ComponentState {
  isFormOK: boolean;
  [fieldName: string]: FieldState
}

Then the [fieldName: string] will exclude isFormOK when type checking the related instance.

Because we need some syntax to describe the actural structure of an object, so maybe reusing the existing syntax but expanding its underneath check will support it easily. Just like flow.js.

Metadata

Metadata

Assignees

No one assigned

    Labels

    DuplicateAn existing issue was already created

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions