Description
TypeScript 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.