futurGH / ts-to-jsdoc

Transpile TypeScript code to fully compatible JavaScript + JSDoc comments.
MIT License
179 stars 17 forks source link

Question about function overloads. #51

Closed smacpherson64 closed 2 months ago

smacpherson64 commented 2 months ago

Hey again,

Are you open to the idea of generating function overloads (with type parameters) in JSDoc?

Going to include a conversation starter PR just in case. If you are not please do not feel any pressure.

Thanks again for your time!

For example, it would transform the following:

/**
 * Creates a curried function to cause an entity to speak.
 *
 * @see {@link speak}
 * @param speech The content to speak.
 * @returns A curried function.
 */
export function speak(speech: string): <T extends {say: (text: string) => void}>(entity: T) => Promise<void>;

/**
 * Causes an entity to speak.
 *
 * @see {@link speak}
 * @param speech The content to speak.
 * @param entity The entity to trigger the speech from.
 * @returns The resulting promise, which resolves when complete.
 */
export function speak<T extends {say: (text: string) => void}>(speech: string, entity: T): Promise<void>;

/**
 * Causes an entity to speak.
 *
 * @param speech The content to speak.
 * @param entity The entity to trigger the speech from.
 * @returns The resulting promise, which resolves when complete.
 */
export function speak(speech: any, entity: any) {
  return entity.say(speech)
}

into something like:

/**
 * Causes an entity to speak.
 *
 * @overload
 * @see {@link speak}
 * @template {{say: (text: string) => void}} T
 * @param {string} speech The content to speak.
 * @param {T} entity The entity to trigger the speech from.
 * @returns {Promise<void>} The resulting promise, which resolves when complete.
 */
/**
 * Creates a curried function to cause an entity to speak.
 *
 * @overload
 * @see {@link speak}
 * @param {string} speech The content to speak.
 * @returns {<T extends {say: (text: string) => void}>(entity: T) => Promise<void>} A curried function.
 */
/**
 * Causes an entity to speak.
 *
 * @param {any} speech The content to speak.
 * @param {any} entity The entity to trigger the speech from.
 * @returns {any} The resulting promise, which resolves when complete.
 */
export function speak(speech, entity) {
  return entity.say(speech);
}
kungfooman commented 2 months ago

This is so nice, thank you for this! I always wanted to have this, but TypeScript was a bit slow to find a "proper" way to do this via JSDoc.

So @overload is a feature since TS 5.0, which hit the stage ~2023, so this should even be the "proper" way of doing it now! :1st_place_medal:

smacpherson64 commented 2 months ago

@kungfooman thanks for the response and encouragement! Happy to be able to contribute.