`typescript/sync`: tuples and type literals from `checker.typeToTypeNode` print multi-line (SingleLine flag lost)

オープン
#64,991 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

@1-DARK がすでに取り組んでいます。

2026年10月30日 から。

  • #65062 @1-DARK による — オープン

評価

難易度
4/5
見積もり時間
3〜5日
初心者へのやさしさ
53/100
issue の種類
バグ
明瞭さ
明確に書かれている
活発さ
活発
技術スタック
node.js, typescript

調査の方向性

Start with the typescript/sync API's checker.typeToTypeNode and api.printer.printNode path, then inspect dist/api/node/encoder.generated.js and how getNodeCommonData encodes multiLine. Compare the emitted node flags with the classic API behavior for tuple and inline object types. Done means the provided reproduction prints [Date, number] and { a: string; } on one line through typescript/sync.

索引モデルが issue の本文から書いたものです。

説明

🔎 Search Terms

typeToTypeNode multiline, printNode single line, EmitFlags SingleLine api, typescript/sync printer, typeToTypeNode tuple printed on several lines

🕗 Version & Regression Information
  • This changed between versions 6.0.2 (classic API) and 7.1.0-dev.20261027.1 (typescript/sync, gitHead 49e69830)
  • not the same as #64429 - that one asks for setEmitFlags on nodes the caller builds. here the checker builds the nodes, and the 6.0 node builder marks them single-line itself
⏯ Playground Link

n/a - needs the typescript/sync API

💻 Code
// input.ts
export type Shape = { tuple: [Date, number]; obj: { a: string } };
// repro.mjs - node 24.18, [email protected]
import path from 'node:path';
import { API } from 'typescript/sync';

const entry = path.resolve('input.ts');
const api = new API({ cwd: process.cwd() });
const program = api.createProgram([entry], { strict: true });
const checker = program.getProject().checker;
const sourceFile = program.getSourceFile(entry);
const alias = sourceFile.statements.find(s => s.name?.text === 'Shape');
const shape = checker.getDeclaredTypeOfSymbol(checker.getSymbolAtLocation(alias.name));
for (const prop of checker.getPropertiesOfType(shape)) {
    const type = checker.getTypeOfSymbol(prop);
    const node = checker.typeToTypeNode(type, sourceFile, 0);
    console.log(`--- ${prop.name}`);
    console.log('printNode:');
    console.log(api.printer.printNode(node));
    console.log(`typeToString: ${checker.typeToString(type)}`);
}
api.close();
🙁 Actual behavior
--- tuple
printNode:
[
    Date,
    number
]
typeToString: [Date, number]
--- obj
printNode:
{
    a: string;
}
typeToString: { a: string; }

the same script on 6.0.2 (ts.createProgram, ts.createPrinter().printNode(ts.EmitHint.Unspecified, node, sourceFile)) prints [Date, number] and { a: string; }

🙂 Expected behavior

printNode gives [Date, number] and { a: string; } on one line, like 6.0 and like typeToString

Additional information about the issue

we generate a big .ts file of request/response types from typeToTypeNode output and are moving the generator from the 6.0 API to typescript/sync. this is the one difference we can't work around - every tuple and inline object type from the checker now takes several lines, and on one of our services ~14.5k of the 16k lines of the generated file change

as far as we can see the node encoder only sends multiLine for blocks and object/array literals (getNodeCommonData in dist/api/node/encoder.generated.js), and PrintNodeOptions only has preserveSourceNewlines, neverAsciiEscape and terminateUnterminatedLiterals, so the client can't ask for single-line. keeping the node builder's single-line flag on these nodes, or a printer option, would both do it for us

主要言語
Go
スター
112k
フォーク
16k
平均マージ
3日 4時間
マージ済み PR(30日)
145

環境構築

Codespaces で開く

このプロジェクトの開発コンテナを、あなたの GitHub アカウントでブラウザ上に起動します。

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

microsoft/TypeScript のほかの issue

microsoft/TypeScript の issue をすべて見る

似ている issue

Go の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。