microsoft / microsoft/TypeScript

[API] No jsDocParsingMode, and reparsed JSDoc types appear as syntax on the declarations they document

Ouverte
#64,070 3 commentaires 0 réactions 1 personne assignée Réclamée par @andrewbranch Voir sur GitHub
API Request
Langage dominant
Go
Étoiles
111k
Forks
14.3k
Merge moyen
2 j 4 h
PR mergées (30 j)
132

Description

### Description

Two related gaps around JSDoc, which together make it hard for a tool that reproduces source text to work with the 7.x API.

**1. There is no `jsDocParsingMode`.** In 6.x a consumer could pass `jsDocParsingMode: JSDocParsingMode.ParseNone` to `createSourceFile` and get a tree with no JSDoc in it. The 7.x API exposes no parse options, and `JSDocParsingMode` is not exported from any path.

**2. JSDoc types are reparsed into the syntax tree.** A `@param`/`@returns` type becomes a real type annotation on the declaration it documents, carrying offsets that point *inside the comment*:

```js
import { API } from "typescript/unstable/sync";
import { NodeFlags } from "typescript/unstable/ast";

// b.js, with allowJs + checkJs:
// /**
// * @param {number} a
// */
// export function g(a) { return a }

const fn = program.getSourceFile("/probe/b.js").statements[0];
const type = fn.parameters[0].type;

type !== undefined // true — the parameter has a type annotation
(type.flags & NodeFlags.Reparsed) !== 0 // true
[type.pos, type.end] // [15, 21] — inside the comment
```

The source has no annotation there. A tool that reads `node.type` and prints it emits syntax the file never contained:

```js
// source
export function resolveMatchingConfig(regularPath, config) { return {} }

// printed back, with the JSDoc types read as syntax
export function resolveMatchingConfig(regularPath, config:Array|Array|[link:string]):base { return {} }
```

`NodeFlags.Reparsed` is exactly the signal needed, and it works — but it has to be consulted at *every* field access, not only when walking children, because `node.type` reaches these nodes directly. That is easy to get wrong and gives no diagnostic when you do.

**3. Syntax errors are reported from inside JSDoc.** With `allowJs`/`checkJs`, malformed JSDoc types produce syntactic diagnostics against the file:

```
(5,74): '}' expected. [1005]
(6,19): '}' expected. [1005]
```

Handing those to a user as parse errors is wrong when the tool does not consume JSDoc at all. Avoiding that is what `ParseNone` was for in 6.x; the only workaround I found is to drop diagnostics whose position falls inside a comment range, which requires scanning the file separately.

### Suggested resolution

Any one of these would be enough for my case, in rough order of preference:

1. A parse option equivalent to `jsDocParsingMode`, on whatever carries parse options when #63875's `createSourceFile` lands.
2. Keeping reparsed nodes off the declaration's own fields (reachable through a dedicated accessor instead), so `node.type` is what the source says.
3. Failing both, documenting that `NodeFlags.Reparsed` must be checked on every node read from a field, and not reporting JSDoc-internal syntax errors as file diagnostics.

### Use case

Porting OpenRewrite's JavaScript/TypeScript parser from the 6.x API. It builds a lossless tree and prints it back byte-for-byte, and it sets `jsDocParsingMode: ParseNone` today precisely because it does not model JSDoc. On 7.x it had to filter `NodeFlags.Reparsed` in two separate places and post-filter diagnostics by comment range to round-trip the same files.

Verified against `7.0.2` and `typescript@next` (`7.1.0-dev.20260827.1`).

Related: #63892 (missing child/token getters) is the other half of what a lossless-syntax consumer needs from this API.

Guide de contribution

Ouvrir le guide de contribution

Évaluation

Cette issue n'a pas encore été évaluée.

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.