Skip to content

Obscure "type cannot be used to index type" error when a mapped type is nested into another mapped type #54289

Description

Bug Report

🔎 Search Terms

  • mapped type
  • nested mapped type

🕗 Version & Regression Information

  • It reproduces in TS of versions from 3.8.3 to 5.0.4 (there are other compiler errors in earlier versions).
  • It reproduces in Nightly (v5.2.0-dev.20230516) as well.
  • I failed to find out a description of similar cases in the FAQ.

⏯ Playground Link

Playground link with relevant code

💻 Code

type Values<T extends object> = T[keyof T]

const ENTITY_CONFIG = {
  'entity1': {
    'step1':  {
      body: { aaa: 1 }
    },
    'step2':  {
      body: { bbb: 1 }
    },
  },
  'entity2': {
    'step1':  {
      body: { ccc: 1 }
    },
    'step2':  {
      body: { ddd: 1 }
    },
  }
} as const

type EntityConfig = typeof ENTITY_CONFIG

type EntityType = Values<{
  [T in keyof EntityConfig]: {
    entityName: T,

    step: Values<{
      [S in keyof EntityConfig[T]]: {
        stepName: S
        body: EntityConfig[T][S]['body'] // <-- TS2536 error
      }
    }>
  }
}>

🙁 Actual behavior

I see an error around the EntityConfig[T][S]['body'] type expression with the following error message: Type '"body"' cannot be used to index type '{ readonly entity1: { readonly step1: { readonly body: { readonly aaa: 1; }; }; readonly step2: { readonly body: { readonly bbb: 1; }; }; }; readonly entity2: { readonly step1: { readonly body: { readonly ccc: 1; }; }; readonly step2: { ...; }; }; }[T][S]'..

Firstly, I don't expect any errors in my type definition. Although it's possible of course that my mental model is wrong, or I don't understand some compiler limitations.

Secondly, the error message is quite obscure to me, it doesn't help to understand what I do wrong and how to fix it.

🙂 Expected behavior

I expect that the EntityType will be successfully constructed and will be something like this:

type EntityType = {
  entityName: 'entity1'
  step: {
    stepName: 'step1'
    body: { aaa: 1 }
  } | {
    stepName: 'step2'
    body: { bbb: 1 }
  }
} | {
  entityName: 'entity2'
  step: {
    stepName: 'step1'
    body: { ccc: 1 }
  } | {
    stepName: 'step2'
    body: { ddd: 1 }
  }
}

In fact, it seems to me based on my "tests" in the playground above that the EntityType type construction works well, despite the error in the type definition.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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