8000 Different inference behaviour between JSX and function call with context sensitive functions. · Issue #50121 · microsoft/TypeScript · GitHub
[go: up one dir, main page]

Skip to content
Different inference behaviour between JSX and function call with context sensitive functions. #50121
Closed
@Mike-Dax

Description

@Mike-Dax

Bug Report

🔎 Search Terms

type inference function arguments, context sensitive function inference

🕗 Version & Regression Information

This is the behaviour in both 4.7.4 and 4.8.0 beta, none of the cases worked before 4.7.

This seems related to #48538

⏯ Playground Link

Playground link with relevant code

💻 Code

interface GlobalState {
  key: number
}

interface ComponentProps<T> {
  accessor: (state: GlobalState) => T
  mutator?: (staging: GlobalState, value: T) => void
}

export function Component<T>(props: ComponentProps<T>) {
  return null
}

// This works
const functionCall1 = Component({
  accessor: state => state.key,
  mutator: (state, value) => {
    state.key = value
  },
})

// This fails 
const functionCall2 = Component({
  mutator: (state, value) => {
    state.key = value
  },
  accessor: state => state.key,
})

// I would expect this to work but it doesn't
const componentCall1 = (
  <Component
    accessor={state => state.key}
    mutator={(state, value) => {
      state.key = value
    }}
  />
)

// This fails 
const componentCall2 = (
  <Component
    mutator={(state, value) => {
      state.key = value
    }}
    accessor={state => state.key}
  />
)

Note that jsx is set to preserve.

🙁 Actual behavior

state.key = value fails with Type 'unknown' is not assignable to type 'number'.(2322)

const componentCall1 = (
  <Component
    accessor={state => state.key}
    mutator={(state, value) => {
      state.key = value
    }}
  />
)

The Component<T> is inferred to be Component<unknown>

🙂 Expected behavior

I would expect it to type check the same as functionCall1

const functionCall1 = Component({
  accessor: state => state.key,
  mutator: (state, value) => {
    state.key = value
  },
})

I'd expect Component<T> to be inferred to be Component<number>

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0