In JSDoc, `?` of conditional is frequently parsed as postfix-`?`
See original GitHub issueTypeScript Version: 3.2.0-dev.20180927 Search Terms: JSDoc conditional types
Using Conditional Types in JSDoc comments confuses the TypeScript parser since the T extends Y ? A : B
syntax looks similar to the Y?
(meaning Y|null
) syntax from JSDoc.
Code
/**
* @template {{}} T
* @param {T} o
* @returns {T extends Readonly<infer U> ? (keyof U)[] : string[]}
*/
function Object_keys(o) {
let keys = Object.keys(o);
// @ts-ignore: Type assertion for stripping `Readonly<…>`
return keys;
}
Expected behavior:
No error should be reported.
The type of Object_keys
should be: <T extends {}>(o: T): T extends Readonly<infer U> ? (keyof U)[] : string[]
.
Actual behavior:
TypeScript compiler shows an error (“?” expected) and mistakes the existing ?
operator for JSDoc <type>|null
syntax.
The actual type therefor ends up being: <T extends {}>(o: T): T extends Readonly<infer U> | null ? (keyof U)[] : string[]
.
Possible fixes:
- When encountering a top-level (not within parenthesis)
?
token in an extends clause, scan ahead and check whether it is followed by an|
or&
token (type intersection or union operators). If yes, treat it as|null
and keep processing; otherwise, assume it’s the start of a conditional type declaration. (Requires at least an LF(2) parser.) - Prohibit the JSDoc
?
operator in the top-level of an extends clause, always causing it to be treated as the start of the conditional type declaration.
Playground Link: None, Playground does not seem to support JavaScript with JSDoc instead of TypeScript as input.
Issue Analytics
- State:
- Created 5 years ago
- Reactions:17
- Comments:11 (9 by maintainers)
Top GitHub Comments
I would like to get rid of jsdoc-style postfix-? semantics entirely, including the parsing. It’s an old syntax copied from Closure that Closure included for backward compatibility. Its remnants are going to cause minor errors like
[?string?]
as long as they’re around.I guess we could still get rid of the jsdoc interpretation of
string?
asstring | null
, if we made sure it wasn’t too big of a breaking change.That may be as close as we get to closing this bug then, because tuples now use postfix-? to indicate optional elements:
[number,string?]
. That means we can’t get rid of postfix-? parsing entirely.