Microsoft/TypeScript

Callback parameter inference not working when part of an inferred tuple type

Open

#52 047 ouverte le 29 déc. 2022

Voir sur GitHub
 (4 commentaires) (1 réaction) (0 assignés)TypeScript (6 726 forks)batch import
BugDomain: check: Contextual TypesHelp Wanted

Métriques du dépôt

Stars
 (48 455 stars)
Métriques de merge PR
 (Merge moyen 6j 17h) (9 PRs mergées en 30 j)

Description

Bug Report

Been experiencing the below problem with no-implicit-any on callback parameter types, when the callback is part of a tuple function-argument, whose type I am inferring.

Was thinking it could be a case of unsupported/incorrect usage on my end, however the type suggestion does appear to be correct on-mouse-hover, so wondering if there's something extra at play.

Might be somewhat related to https://github.com/microsoft/TypeScript/issues/44476 but not sure.

🔎 Search Terms

Tuple, callback, generic, inference

🕗 Version & Regression Information

This is the behavior in every version I tried since 4.0 that brought support for variadic tuples, and I reviewed the FAQ for entries about generics/tuples/callbacks

⏯ Playground Link

Playground link with relevant code

(for context, if the above example feels a bit contrived: the actual use-case involves typing/checking a function argument that can be a variadic tuple with multiple complex elements, using a more complex utility type. If interested here's a second playground link with the whole shebang - but in the first one I've tried to pare it down to the most basic example with just 1 element on the tuple)

💻 Code


type Options<T = unknown> = {
  inputData: T;
  handler: (t: T) => void
}

type ElemOptions<T> = T extends { inputData: infer X } ? Options<X> : never

type TupleOptions<
  T extends any[],
> = T extends [infer Elem]
  ? [ElemOptions<Elem>]
  : T
  
function fooWithTuple<T extends any[]>(bar: readonly [...TupleOptions<T>]) {
  return
}

fooWithTuple([{
  inputData: 'string',
  // Error: Parameter 'x' implicitly has an 'any' type.
  // even though hovering over `handler` correctly labels it as `handler: (t: string) => void`
  handler: (x) => {}
}])

// included in the playground link but not shown here:
//  (1) type-inference all works fine when you're not dealing with a tuple, and
//  (2) type-checking in a tuple works correctly when you add the param type explicitly

🙁 Actual behavior

Handler complains about no-implicit-any, even though type-suggestion work as expected, and type-checking works if you add the param type explicitly.

🙂 Expected behavior

Handler parameter type can be inferred automatically; no no-implicit-any complaints.

Guide contributeur