Skip to content

Type of symbol-named computed property is contextually typed with string literal #43628

@christianalfoni

Description

@christianalfoni

Bug Report

🔎 Search Terms

symbol
index
extends

🕗 Version & Regression Information

Version 4.2.3 and all previous version. Does not work in 4.3.0 Beta either

  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about indexing symbols and extending

⏯ Playground Link

Playground link with relevant code

💻 Code

export interface TContext {
  state: string;
}

export interface TAction {
  type: string | symbol;
}


export type TTransitions<C extends TContext, A extends TAction, NewState extends C['state']> = {
  [State in C['state']]: {
    [Type in A['type']]?: (
      action: A & { type: Type },
      state: C extends { state: State } ? C : never,
    ) => C extends { state: NewState } ? C : never;
  };
};

const transition = <C extends TContext, A extends TAction, NewState extends C['state']>(
  state: C,
  action: A,
  transitions: TTransitions<C, A, NewState>,
): C => {
 return {} as any
}

const A = Symbol('A')
const B = Symbol('B')

type Context = {
  state: 'FOO'
} | {
  state: 'BAR'
}

type Action = {
  type: typeof A
  data: string
} | {
  type: typeof B
  data: number
}

const context: Context = {} as any
const action: Action = {} as any

transition(context, action, {
  // When I hover this FOO I can see the correct typing of the [A]: (action) => ({ state: 'BAR' }). It states
  // that the "action" argument indeed is a `{ type: typeof A, data: string }` type
  FOO: {
    // But here the "action" argument becomes `never`
    [A]: (action) => ({ state: 'BAR' })
  },
  BAR: {}
})

🙁 Actual behavior

The "action" argument becomes never

Here I am hovering the FOO property
Screenshot 2021-04-10 at 14 50 36

Here I am hovering the action argument
Screenshot 2021-04-10 at 14 50 41

🙂 Expected behavior

The "action" argument should have had the same type as when hovering the "FOO" property:

{
  type: typeof A;
  data: string;
} & {
  type: typeof A;
}

Metadata

Metadata

Assignees

Labels

BugA bug in TypeScriptFix AvailableA PR has been opened for this issueRescheduledThis 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