microsoft / microsoft/TypeScript

JSDOC generics bug for callbacks when args are present

Open
#61,090 3 comments 1 reaction 0 assignees View on GitHub
Bug Domain: JSDoc Help Wanted
Dominant language
Go
Stars
111k
Forks
14.3k
Avg merge
2d 4h
Merged PRs (30d)
132

Description

### 🔎 Search Terms

"Generics", "JSDOC", "Callback"

### 🕗 Version & Regression Information

TS 5.7.3
v5.8.0-dev.20250131

### ⏯ Playground Link

https://www.typescriptlang.org/play/?filetype=js#code/PQKgUGBSDKAiDyBhABAcwKYDt0CcCWAxgM7IBGArqsgGYD2OyBAhgDYulMEDWJA7gBZZkTHKhIj0yAA450RLABcIASUzIFgmrTa1eeTFXQAPJgFspLdABpkAAwAm6avvQAKAJS3kRfrXIt7ZFkFchw1WwA1RAAeaAA+WxsKBWQBIRFUMFtmNg5uL34mcVESPBT7WjlkTFoU2SJtADdJW2gvJkxA4NDMEkiYjoBPBIA6CBBgCFBwZBBkAAEFdHMWJiXkaDBZhakRM2QAb1cMgAYALkPkWlJ5HGacC4BReGQAX3dkAF44jdfGVnYnC4yC2c3muxw+wO8CkCjwtF6fwA2rRYfDegBdEHbebdMIkA5RWJxV6gyagUELBSDKSSA7IYmuaiYC7HUTnS7XW73J7wADcbw+3w2NlRcIRRAA-BcYeLekKfkT4m8yWBqORMAQ5chHM5sK4coDuKK0RKPgctsgrQQJSl6ZgzJI-p8rqbeshJZLDqSrdbbVcbrh7l9quheMhnh5LX7eikiAo1pIXYa8lxXPSuUHcILo0F0CEwqHw1FXPHE+4wKSwNNKYtlhZExtVQRVkQSFFDrnplSaXToH8Jrmy0suyAZr6cRCof3vAn1rnZpMJzbYzhyFr6KW5+hzQvfRo8EQRsOk7PE7nSVXu4te7rDvbHdLZ-gDG8-rL0SRB2AW0USM9vSmYBkAAQVEOwUyBLw9A0YQSmQABaZAYAQFAKjkTAAHI6jkJpJGgMZgGAlCkGXf1GgARguIkhjiatgIAFWgCdfRXeNkEo6iYlIWhtHQDo6LYlJKJDXUXFcNlUBOBV1DXaxLgdUx0AuTDdSYfwFEwnN6NA8DsgBVNoLKXxyBSDISCQki0MqEh6jwjZCOIuBSNY8iACYuOiHi+IEnSmJYmN2MaDzkCJbzLF8oSOLc0SnHEjwvh+BQ5JsB8lJUtSNK094wCAA

### 💻 Code

In the following example, `define()` should return `VC`, but when arg `callback` has args it does not resolve `S` and returns `VC`.

```js
/**
* @template S
* @param {(arg0: { observer: EO }) => S} callback
* @param {Options} [options]
* @returns {VC}
*/
/*
* @type { (fn: (arg0: { observer: EO; }) => S, options?: Options) => VC }
*/
function define(callback, options) {
const { name } = options ?? {}
const observer = new EO()
const state = callback({ observer })
return new VC(state)
}

/**
* @template S
*/
class VC {
/** @type {S} */
state
/**
* @param {S} state
*/
constructor(state) {
this.state = state
}
}

/** @typedef {{ name?: string }} Options */

class EO {}

// Arg `callback` with args - JSDOC doesn't resolve S.
// JSDOC const v1: VC
// TS const v1: VC
const v1 = define((arg0) => true, { name: 'default' })

// Arg `callback` without args - JSDOC does resolve S.
// JSDOC const v2: VC
// TS const v2: VC
const v2 = define(() => true, { name: 'default' })

```

### 🙁 Actual behavior

JSDOC doesn't resolve S

### 🙂 Expected behavior

JSDOC should resolve S in the same way as TS.

### Additional information about the issue

_No response_

Contributor guide

Open the contributing guide

Research direction

Start with the linked TypeScript Playground repro and compare the inferred types of v1 and v2 with the expected TypeScript results. Trace the JSDoc generic callback inference path in the compiler, then add a regression test showing that v1 is inferred as VC when the callback has an argument.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, 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.