microsoft / microsoft/TypeScript
[API] No jsDocParsingMode, and reparsed JSDoc types appear as syntax on the declarations they document
@andrewbranch 已经在做这个了。
开始于 2026年8月28日。
- 主要语言
- Go
- 星标
- 111k
- 派生
- 14.3k
- 平均合并
- 2 天 4 小时
- 30 天内合并 PR
- 132
描述
### 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.
贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
评估
这个 Issue 还没有评估数据。