microsoft / microsoft/TypeScript

Unexpected type infer for function first argument with default value since 5.1

Open
#57,706 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Domain: check: Type Inference Help Wanted Possible Improvement
Dominant language
Go
Stars
111k
Forks
14.3k
Avg merge
1d 19h
Merged PRs (30d)
117

Description

🔎 Search Terms

"type infer first argument"

🕗 Version & Regression Information
  • This is a crash
  • This changed between versions v5.0.4 and v5.1.6
  • This changed in commit or PR _______
  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about _________
  • I was unable to test this on prior versions because _______
⏯ Playground Link

https://www.typescriptlang.org/play?ts=5.5.0-dev.20240308#code/CYUwxgNghgTiAEAzArgOzAFwJYHtXy1URBgEYAeAFQD4AKRVALngDEpMcYBPK6gSmaUAUKEiwEKdNjwEiJAEy96TVuwycuimgPjChIAB4AHThngYuRhGw7de8ALzxasAOalBAGnhv5zKKhcfI7UPoH6xqbmltZqGlqhTrQAdKluAM7MANqU3gFcALrBDqH5QuVgeOlmiKSOzgC26a7M1TCErvUA5AAWIBAQOF3eGCDV-oHFoQDe8AC+QpWo1T51ToTEZPSkfEIA9HvwR-AAegD8i1VmUPL1GwrbuwfHpxeXyzW3SU0t8G0d3T6AyGU3gswWSxWACM7nItoh5E9Dsdzu9oWtZJt5PREftkUdUWizGBYZtSLRaD9Whh2qhOk5ev1Bl1QeCkS9UZDiV9MQ9Kc1qbT6fBGcCWSEwfN2Si3kA

💻 Code
export type Factory<T> = (arg1: T, arg2: any) => any
export type Factory2<T> = (...args: [T, any]) => any

declare function infer1<T>(fn: Factory<T>): T
declare function infer2<T>(fn: Factory2<T>): T

const f1 = (msg: string = 'hello', test: any) => { }
const a1 = infer1(f1)
//    ^? const a1: string | undefined
const a2 = infer2(f1)
//    ^? const a2: string | undefined

const f2 = (msg: string = 'hello') => { }
const b = infer1(f2)
//    ^? const b: string | undefined
const b1 = infer2(f2)
//    ^? const b1: string | undefined

const c = infer1((msg: string = 'hello') => { })
//    ^? const c: string
const c2 = infer2((msg: string = 'hello') => { })
//    ^? const c2: string | undefined
🙁 Actual behavior

In my code you'll notice that the type of c is not the same as b, but the argument we passing into function infer1 is actually the same.

I've tested this between v5.0.4 and v5.1.6, but the type of c is different:

// v5.0.4
const c: string | undefined

// v5.1.6
const c: string

After checking v5.1 changelog, I'm still not sure what changes have been made between 5.0 to 5.1.

So I decided to submit this issue as a "Bug report".

🙂 Expected behavior

The type of c is supposed to be string | undefined.

Additional information about the issue

No response

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the linked TypeScript Playground and reduce the provided generic inference examples while comparing TypeScript 5.0.4 with 5.1.6. Trace the type inference behavior for defaulted first parameters and determine whether the reported result should consistently include undefined; done means the minimal repro matches the expected type without regressing the related cases.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.