Skip to content

Type 'keyof T' cannot be used to index type 'T extends <type>' with unions in v4.4.4 and newer #46495

Closed
@Basssiiie

Description

@Basssiiie

Bug Report

🔎 Search Terms

  • Type cannot be used to index type
  • keyof union type index

This one was kinda hard to find search terms for, I mainly look at changes between v.4.3.5 and v.4.4.4 in the changelog and could not find anything that could have potentially caused this.

🕗 Version & Regression Information

This changed between versions v4.3.5 and v4.4.4. It works fine on TS Playground on v4.3.5 and earlier but errors on v4.4.4 and later.

⏯ Playground Link

Playground link with relevant code

💻 Code

Same as TS Playground link minus workaround comments:

interface Button 
{
  type: "button";
  text: string;
}

interface Checkbox 
{
  type: "checkbox";
  isChecked: boolean;
}

type Control = Button | Checkbox;

function update<T extends Control, K extends keyof T>(control : T | undefined, key: K, value: T[K]): void
{
  if (control !== undefined)
  {
    control[key] = value; // this breaks on v4.4.4 but works on v4.3.5
  }
}

🙁 Actual behavior

When running the code above in v4.4.4 and later versions it errors on the last line (control[key] = value;) with:

Type 'K' cannot be used to index type 'Control'.

When transpiling the code on v4.3.5 and earlier it works fine.

Both these two workarounds work on all versions:

(control)[key] = value; // add parentheses
const c = control; // use inline variable
c[key] = value;

It seems like control is resolved to type Control in the bugged snippet but resolves to T extends Control in the other snippets.

Also sidesnotes: the error goes away if | undefined is removed from the parameter type, and also if T is changed to something that is not an union.

🙂 Expected behavior

I would expect control would resolve to T extends Control in all 3 snippets of the code.

Thank you all for your time. :)

Metadata

Metadata

Assignees

Labels

BugA bug in TypeScriptFix AvailableA PR has been opened for this issue

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions