Skip to content

Different inference behaviour between JSX and function call with context sensitive functions. #50121

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>

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

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions