Skip to content

Parameter type isn't inferred in values of mapped type with as. #46602

Open
@strout

Description

@strout

Bug Report

I came across this odd behavior while doing Day 5 of "Type | Treat".

🔎 Search Terms

as mapped function parameter infer

🕗 Version & Regression Information

  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about Type System Behavior.

I tried every Playground version with as support.

⏯ Playground Link

Playground link with relevant code

💻 Code

function bug<Es extends 'foo' | 'bar'>(_: { [E in Es as `on${E}`]: (e: string) => void }) {
}

bug({
  onfoo(_e) {}, // _e: any; onfoo: (e: string) => void
  onbar(_e) {}  // _e: any; onbar: (e: string) => void
})

function workaround_1<Es extends 'foo' | 'bar'>(_: { [E in `on${Es}`]: (e: string) => void }) {
}

workaround_1({
  onfoo(_e) {}, // _e: string
  onbar(_e) {}  // _e: string
})

function workaround_2<Es extends 'foo' | 'bar'>(_: Es extends never ? {} : { [E in Es as `on${E}`]: (e: string) => void }) {
}

workaround_2({
  onfoo(_e) {}, // _e: string
  onbar(_e) {}  // _e: string
})

🙁 Actual behavior

The types of onfoo and onbar are correctly inferred as (e: string) => void but the parameter _e is incorrectly typed as any instead of string.

🙂 Expected behavior

I would expect _e to have type string, because it's known that the function has type (e: string) => void. I provided two variations that are typed correctly -- one without using as, and one forcing the type to be conditional on Es. All three should be equivalent. I'm especially surprised that bug and workaround_2 behave differently since it's (presumably) just forcing Es to be evaluated slightly earlier.

Metadata

Metadata

Assignees

Labels

Needs InvestigationThis issue needs a team member to investigate its status.RescheduledThis issue was previously scheduled to an earlier milestone

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions