You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
interfaceMatcherObj{name: string;}typeMatcherFn=(name: string)=>booleantypeMatcher=MatcherObj|MatcherFntypeMapTuple<KeysTupleextendsunknown[],MapToValue>={[IndexinkeyofKeysTuple]: MapToValue;}interfaceDefinition<MatchersTextendsMatcher[]>{matches: [...MatchersT];computeValueFromMatches: (
...matches: MapTuple<MatchersT,Matcher[]>)=>number;}interfaceConfig<Defsextends{[KinkeyofDefs]: Definition<any>}>{definition: Defs;}functioncreate<Defsextends{[KinkeyofDefs]: Matcher[]}>(config: Config<{[KinkeyofDefs]: Definition<Defs[K]>}>){// ...}create({definition: {valid: {matches: [{name: "m3"}],computeValueFromMatches: (m)=>m.length,},too_mang_args: {matches: [{name: "m1"},{name: "m2"}],// below correctly errors "Target signature provides too few arguments. Expected 3 or more, but got 2."computeValueFromMatches: (m1,m2,m3)=>m1.length+m2.length,},not_enough_args: {matches: [],// below correctly errors "Target signature provides too few arguments. Expected 1 or more, but got 0."computeValueFromMatches: (m)=>123},// valid_using_function: {// matches: [(a) => a === 'x'],// computeValueFromMatches: (m) => m.length// },// as soon as you uncomment 'valid_using_function' all the errors go away, and inference breaks!},})
🙁 Actual behavior
When all elements in the matches tuple are object literals, TypeScript infers an exact tuple type (e.g. [MatcherObj] or [MatcherObj, MatcherObj]), and the signature of computeValueFromMatches enforces the correct number of arguments.
However, if a function literal (or an object with a function as a property) is included in the tuple—as shown in the commented-out valid_using_function case — the inference for ALL the cases breaks (not just the one property!), as the entire type widens to MatcherObj[].
This causes the relationship between the number of tuple elements and the number of parameters expected by computeValueFromMatches to be lost, so TypeScript no longer emits errors for other keys when the number of parameters is incorrect.
🙂 Expected behavior
TypeScript should preserve the literal tuple type even when a function literal is included.
In the example case, the tuple length of the matches property should be inferred exactly as provided, so that computeValueFromMatches enforces a parameter count matching the tuple length.
This behavior should be consistent regardless of whether the tuple elements are object literals or function literals.
Additional information about the issue
This issue does not occur when using object literals exclusively in the matches tuple. It only manifests when a function literal is included, suggesting that the inference algorithm incorrectly widens the tuple type in that scenario.
What's even more bizarre, even if you change the Matcher type to be an object whose a property can be a function, the same issue occurs! i.e.
This is, at the very least, a duplicate of #56241 . The situation presented here is a little bit more complex so maybe fixing it would require some extra work beyond fixing #56241 but that's hard to tell on the spot
🔎 Search Terms
🕗 Version & Regression Information
⏯ Playground Link
Playground
💻 Code
🙁 Actual behavior
When all elements in the
matches
tuple are object literals, TypeScript infers an exact tuple type (e.g.[MatcherObj]
or[MatcherObj, MatcherObj]
), and the signature ofcomputeValueFromMatches
enforces the correct number of arguments.However, if a function literal (or an object with a function as a property) is included in the tuple—as shown in the commented-out
valid_using_function
case — the inference for ALL the cases breaks (not just the one property!), as the entire type widens toMatcherObj[]
.This causes the relationship between the number of tuple elements and the number of parameters expected by
computeValueFromMatches
to be lost, so TypeScript no longer emits errors for other keys when the number of parameters is incorrect.🙂 Expected behavior
TypeScript should preserve the literal tuple type even when a function literal is included.
In the example case, the tuple length of the
matches
property should be inferred exactly as provided, so thatcomputeValueFromMatches
enforces a parameter count matching the tuple length.This behavior should be consistent regardless of whether the tuple elements are object literals or function literals.
Additional information about the issue
This issue does not occur when using object literals exclusively in the
matches
tuple. It only manifests when a function literal is included, suggesting that the inference algorithm incorrectly widens the tuple type in that scenario.What's even more bizarre, even if you change the Matcher type to be an object whose a property can be a function, the same issue occurs! i.e.
As soon as any of the defined
matches
uses a function under thename
property, e.g.{ name: () => true }
, causes same widening behavior!I have thoroughly searched the TypeScript repository and online discussions but have not found a related issue.
The text was updated successfully, but these errors were encountered: