Description
🔎 Search Terms
infer
@type
strict
JSDoc
Parameters
Function
🕗 Version & Regression Information
- This is the behavior in every version I tried, and I reviewed the FAQ for entries about type inference.
I've pulled the latest version of this repository and made a test case in the "fourslash" section, which demonstrates the problem I see.
(I couldn't see how to do something like this in the playground, sorry. Commit is linked)
⏯ Playground Link
💻 Code
// In file func.js
export function func(/** @type {string} */ param) {};
// In file use-it.js
import { func } from "./func.js";
type FuncParam = (typeof func) extends (...args: infer P) => any ? P : never;
// ^ never, but expected [param: string]
In tsconfig.json:
{
"compilerOptions": {
"allowJs": true,
"checkJs": true,
"noEmit": true,
"strict": true
}
}
(The above definition is obviously just Parameters<T>
, but put in full for comparison with another example below)
🙁 Actual behavior
The type FuncParam
resolved to never
(i.e. it took the false branch of the ternary)
🙂 Expected behavior
The type FuncParam
should be [param: string]
, as given by the JSDoc @type
tag
Additional information about the issue
This seems like a bug because all other ways of specifying the func
function with JSDoc or the FuncParam
type seemed to work as expected:
- Using the
@param
tag instead:
/**
* @param {string} param
*/
export function func(param) {};
yields FuncParam
→ [param: string]
- Using a union with
undefined
works, but is not what I want for the definition offunc
:
export function func(/** @type {string | undefined} */ param) {};
yields FuncParam
→ [param?: string | undefined]
- Trying the conditional without
infer
works (but is not usable for the intended purpose):
import { func } from "./func.js";
type FuncIsAFunc = (typeof func) extends (...args: any) => any ? 'good' : never;
// ^ 'good'
- Pulling just the first parameter out also works (but obviously that's not how
Parameters<T>
works):
import { func } from "./func.js";
type FuncParam = (typeof func) extends (arg: infer A) => any ? A : never;
// ^ string
This also only seemed to occur specifically with strict: true
. I couldn't see this with any of the other strict...
options (though I may have missed something here)
All other views on the function seems to show that it is happily a function with a string parameter. i.e. the tooltip hover over func
, while inside use-it.ts
shows:
(alias) function func(param: string): void
import func
The output I see from the single test linked above (using hereby runtests --tests=jsDocInferredFunctionParameters
) is:
1) fourslash tests
tests/cases/fourslash/jsDocInferredFunctionParameters.ts
fourslash test jsDocInferredFunctionParameters.ts runs correctly:
AssertionError: At marker '': quick info text: expected 'type FuncParam = never' to equal 'type FuncParam = [param: string]'
+ expected - actual
-type FuncParam = never
+type FuncParam = [param: string]
at _TestState.verifyQuickInfoString (src\harness\fourslashImpl.ts:1863:16)
at Verify.quickInfoIs (src\harness\fourslashInterfaceImpl.ts:268:20)
at eval (jsDocInferredFunctionParameters.js:13:8)
at runCode (src\harness\fourslashImpl.ts:4618:9)
at runFourSlashTestContent (src\harness\fourslashImpl.ts:4576:5)
at runFourSlashTest (src\harness\fourslashImpl.ts:4559:5)
at Context.<anonymous> (src\testRunner\fourslashRunner.ts:59:39)
at processImmediate (node:internal/timers:476:21)
This also happens for arrow functions and class methods, e.g.
// In func.js
export const func = (/** @type {string} */ param) => {};
export class Cls{
method(/** @type {string} */ param) {}
}
with similar code as for FuncParam
.