color-js / color.js

Color conversion & manipulation library by the editors of the CSS Color specifications
https://colorjs.io
MIT License
1.81k stars 80 forks source link

[types] JSDoc overloads don't seem to work with declarations #573

Closed MysteryBlokHed closed 1 week ago

MysteryBlokHed commented 1 week ago

It doesn't look like the @overload tag works properly when generating declarations from JSDoc. It works fine when the JavaScript files are referenced directly, but not when they're converted to .d.ts files.

As an example, here's the JSDoc for the range function:

https://github.com/color-js/color.js/blob/c99665cb2dfb9e1cefb1f6c764a41b9af7cc89e2/src/interpolation.js#L138-L155

And here's the generated .d.ts:

/**
 * Creates a function that accepts a number and returns a color.
 * For numbers in the range 0 to 1, the function interpolates;
 * for numbers outside that range, the function extrapolates
 * (and thus may not return the results you expect)
 * @overload
 * @param {Range} range
 * @param {RangeOptions} [options]
 * @returns {Range}
 */
/**
 * @overload
 * @param {ColorTypes} color1
 * @param {ColorTypes} color2
 * @param {RangeOptions & Record<string, any>} [options]
 * @returns {Range}
 */
export function range(color1: ColorTypes, color2: ColorTypes, options?: RangeOptions & Record<string, any>): Range;

Notably, all TypeScript decides to do is to simply take the types from the final overload comment, and then apply those to the function. It does not generate the necessary overload signatures. And since this is now a TypeScript file, the JSDoc type hints are completely ignored.

This is a pretty important blocker for v0.6.0 IMO. I'd appreciate any input as to how we should fix this.

cc @jgerigmeyer @lloydk

lloydk commented 1 week ago

I see this for the range function in interpolation.d.ts when I run build:ts with Typescript 5.4.5:

/**
 * Creates a function that accepts a number and returns a color.
 * For numbers in the range 0 to 1, the function interpolates;
 * for numbers outside that range, the function extrapolates
 * (and thus may not return the results you expect)
 * @overload
 * @param {Range} range
 * @param {RangeOptions} [options]
 * @returns {Range}
 */
export function range(range: Range, options?: RangeOptions): Range;
/**
 * @overload
 * @param {ColorTypes} color1
 * @param {ColorTypes} color2
 * @param {RangeOptions & Record<string, any>} [options]
 * @returns {Range}
 */
export function range(color1: ColorTypes, color2: ColorTypes, options?: RangeOptions & Record<string, any>): Range;
MysteryBlokHed commented 1 week ago

Huh. I'll double-check my TypeScript version and try again

MysteryBlokHed commented 1 week ago

Nevermind; it looks like for whatever reason my global tsc was on an old version.

In my defence, I am very tired today.