-
Notifications
You must be signed in to change notification settings - Fork 12.9k
Description
Bug Report
🔎 Search Terms
Um, aside from the words in the subject line, I guess "confusing"?
🕗 Version & Regression Information
Seen in 5.0.0-beta and 5.0.0-dev.20230217
- I was unable to test this on prior versions because
@overload
is new in 5.0.0
💻 Code
// @checkJs: true
// @strict: true
// @outDir: dist/
// @declaration: true
// @filename: jsFileFunctionOverloads.js
/**
* @template T
* @param {T} x
* @returns {T}
*/
const identity = x => x;
/**
* @overload
* @template T
* @template U
* @param {T[]} array
* @param {(x: T) => U[]} iterable
* @returns {U[]}
*/
/**
* @overload
* @template T
* @param {T[][]} array
* @returns {T[]}
*/
/**
* @param {unknown[]} array
* @param {(x: unknown) => unknown} iterable
* @returns {unknown[]}
*/
function flatMap(array, iterable = identity) {
/** @type {unknown[]} */
const result = [];
for (let i = 0; i < array.length; i += 1) {
result.push(.../** @type {unknown[]} */(iterable(array[i])));
}
return result;
}
⏯ Playground Link
AST Viewer link (Unfortunately, I couldn't figure out how to set the options in the link; set Version to "@next (5.0.0-dev-[...])" and Script Kind to "ts.ScriptKind.JS".)
🙁 Actual behavior
When the @overload
is written before a @template
tag, the overload signature ends at the @template
tag, and the only sign that this has happened is the error message "This overload implicitly returns the type 'any' because it lacks a return type annotation." highlighting only the word "overload" (with no indication of where signature parsing stopped), and even that only happens in strict mode (not sure which exact flag).
(Unfortunately, the bug workbench won't actually show you the proper error highlights, and I found it too difficult to manage the settings in the standard Playground. I mean ... dozens of checkboxes??? Huh?)
P.S.
I've noticed that there's nowhere to hover that shows you TypeScript's understanding of the overload signatures; hovering the function's name only shows you function flatMap(array: any, iterable?: (x: any) => any): any[] (+2 overloads)
. Stranger yet, // ^?
shows that on the editor but when you look at the "Asserts" tab it says "function flatMap<T, U>(): any (+1 overload)". (Fiddling around locally indicates that hovering in vscode would also give just (+1 overload).)
Conclusion: the workbench's editor is feeding the twoslash document straight to TypeScript along with the individual files ... and, when processed as TypeScript, the JSDoc @overload
s are ignored and the function is given the implementation type as its declared type, but the other output Workbench shows is from an entirely distinct instance of TypeScript.
🙂 Expected behavior
I would expect this to either work, or give clear diagnostics saying that you have to put @template
before @overload
, because it's not at all obvious that this would be required; it's not like there's an analogous overload
keyword in TypeScript that comes after the type parameter list but before the ordinary parameter list or something. (I ... actually just checked to make sure that's true, because sometimes I have a terrible memory.)