Closed
Description
Search Terms
template default types, template default jsdoc, generic default jsdoc
Suggestion
In pure TypeScript we can have default values for generic parameters e.g.:
type LessThan<T> = (a: T, b: T) => boolean;
class PriorityQueue<Value, Priority=number> {
_comparePriority: LessThan<Priority>;
constructor(comparePriority: LessThan<Priority> = (a, b) => a < b) {
this._comparePriority = comparePriority;
// ...
}
add(value: Value, priority: Priority) {
// ...
}
pop(): Value {
// ...
}
}
const queue: PriorityQueue<Person, [number, string]>
= new PriorityQueue(compareByAgeThenAlphabetical)
However there doesn't seem to be a way to represent this in JSDoc, TypeScript seems to just split @template
on comma and take the longest identifier.
This proposal is to extend @template
in JSDoc to support generic defaults (e.g. Priority=number
).
Bikeshed syntax
The syntax isn't really important, but the capability would be helpful. I don't think this would cause any grammar issues but I'm not sure.
/**
* @template Value, Priority=number
*/
Use Cases
Same as within TypeScript, just extended to JSDoc.
Example with bikeshed syntax
/**
* @template T
* @typedef {(a: T, b: T) => boolean} LessThan
*/
/**
* @template Value
* @template Priority=number
*/
class PriorityQueue {
/** @type {LessThan<Priority>} */
_comparePriority;
/**
* @param {LessThan<Priority>} [comparePriority]
*/
constructor(comparePriority=(a, b) => a < b) {
this._comparePriority = comparePriority;
// ...
}
/**
* @param {Value} value
* @param {Priority} priority
*/
add(value, priority) {
// ...
}
/**
* @returns {Value}
*/
pop(): Value {
// ...
}
}
/** @type {PriorityQueue<Person, [number, string]>} */
const queue = new PriorityQueue(compareByAgeThenAlphabetical)
Checklist
My suggestion meets these guidelines:
- [✓] This wouldn't be a breaking change in existing TypeScript/JavaScript code
- [✓] This wouldn't change the runtime behavior of existing JavaScript code
- [✓] This could be implemented without emitting different JS based on the types of the expressions
- [✓] This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, etc.)
- [✓] This feature would agree with the rest of TypeScript's Design Goals.
Metadata
Metadata
Assignees
Labels
Type
Projects
Milestone
Relationships
Development
No branches or pull requests
Activity
[-]Template default types in JSDoc[/-][+]@template generic default types in JSDoc[/+][-]@template generic default types in JSDoc[/-][+]default types for @template generics in JSDoc[/+]SamB commentedon Jul 16, 2019
Well, I like the color of your bikeshed. You know, as long as it doesn't end up making anything explode :-).
VincentGuinaudeau commentedon Oct 25, 2019
In the case of functions, typescript could also infer the default value of a generic parameter from the default value of the parameter it is bounded to.
Example :
Here I would expect Typescript to infer that the type of
test1
isnumber[] | null
, and the type oftest2
isnumber[]
.Currently (version 3.6.4), typescript return an error on the parameter
defaultValue = null
:rohit-gohri commentedon Apr 8, 2020
As jsdoc checking already supports the extends syntax (https://www.typescriptlang.org/docs/handbook/type-checking-javascript-files.html#template), i,e, this is valid:
It'd be better to just extend that and add support for an
=
sign there:Matches nicely to Equivalent ts:
@template
tag does not generate generic parameters englercj/tsd-jsdoc#134thw0rted commentedon May 29, 2020
The OP's "bikeshedding" does not give a syntax for a type parameter that is both constrained and includes a default value. I would submit that it probably makes sense to support
@template {BaseType} T=DefaultType
rather than@template {BaseType=DefaultType} T
. The former syntax more closely matches@param
, and I don't think there are any other examples of syntax similar to the latter, as far as I can see.Has there been any opinion from the team about this? (I see @weswigham is the only contributor participating?) I just linked to this issue from
tsd-jsdoc
and it would be great iftsd-jsdoc
and the TS team could all align on a syntax that works for everybody.trusktr commentedon Jun 6, 2020
A problem with that is the
=
means anoptional
type in JSDoc syntax. I tried that in TypeScript playground, and@template {number = null} T
results inT extends number | undefined
.We must find a way to do this without breaking JSDoc syntax.
thw0rted commentedon Jun 8, 2020
@trusktr that's another argument in favor of a
@param
-like syntax:Though, to be fair,
@template
is not specified in core JSDoc, it's a Closure extension, so the JSDoc compiler should already be ignoring it.michaelfig commentedon Aug 10, 2020
Is there any agreement on a way forward, to the extent that a PR would be welcome?
This is a pretty severe blocker for me, since I express all my types in JSDoc, and want to add template parameters in a backward-compatible way (especially to take an existing type and turn it into a template without breaking callers). My only other option that I'd prefer not to, is to move the (many interdependent) declarations into a
.d.ts
and rewrite them as Typescript.bhgsbatista commentedon Dec 17, 2020
I want to chime in as well, I've been using JSDoc as a way to add compile safety to my plain JS code, and it's been a mostly pleasant experience, until I hit this limitation.
I second the following syntax, as it preserves the current behavior and mirrors default type assignments in TypeScript:
jonlepage commentedon Mar 15, 2021
why not just keep jsdoc syntax ?
Example:
we need a support for this :)
thw0rted commentedon Mar 15, 2021
keyof
andtypeof
are Typescript, and vanilla JSDoc would have no idea what to do with them.jhunterkohler commentedon Jul 3, 2021
I'm loosing my mind, the lack of this feature is making stuff impossibly hard.
alexander-akait commentedon Aug 26, 2021
Very very bad.... Need update generated types manually 😞
intrnl commentedon Sep 18, 2021
doesn't #45483 resolve this?
alexander-akait commentedon Sep 18, 2021
Yep
Jamesernator commentedon Sep 18, 2021
Yes, I'll close this now.