- 
                Notifications
    You must be signed in to change notification settings 
- Fork 13.1k
Closed
Labels
Experience EnhancementNoncontroversial enhancementsNoncontroversial enhancementsHelp WantedYou can do thisYou can do thisSuggestionAn idea for TypeScriptAn idea for TypeScript
Milestone
Description
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>
Morritz, codebutler, moishinetzer and jnicklas
Metadata
Metadata
Assignees
Labels
Experience EnhancementNoncontroversial enhancementsNoncontroversial enhancementsHelp WantedYou can do thisYou can do thisSuggestionAn idea for TypeScriptAn idea for TypeScript