Include available printers in plugin type declarations (#18706)

Co-authored-by: fisker <lionkay@gmail.com>
This commit is contained in:
Dom Poradaandfisker authored and fisker committed 2026-01-22 01:39:57 +08:00
1 parent bece827851
commit 57f702f765
3 files changed
+57 -7

No files matched your search

+15
View File
@@ -0,0 +1,15 @@
#### Include available `printers` in plugin type declarations (#18706 by @porada)
<!-- prettier-ignore -->
```ts
// Input
import * as prettierPluginEstree from "prettier/plugins/estree";
// Prettier stable
// Property 'printers' does not exist on type 'typeof import("prettier/plugins/estree")'. ts(2339)
prettierPluginEstree.printers.estree; //=> any
// Prettier main
prettierPluginEstree.printers.estree; //=> Printer
prettierPluginEstree.printers["estree-json"]; //=> Printer
```
+38 -7
View File
@@ -36,15 +36,19 @@ async function buildPluginTypes({ packageConfig, file: { input, output } }) {
);
const plugin = pluginModule.default ?? pluginModule;
const parserNames = Object.keys(plugin.parsers ?? {});
const printerNames = Object.keys(plugin.printers ?? {});
const typesImportPath =
packageConfig.packageName === "prettier" ? "../index.js" : "prettier";
// We only add `parsers` to types file, printers should not be used alone
// For `estree` plugin, we just export an empty object to ensure it treated as a module
const code =
parserNames.length === 0
? "export {};"
: outdent`
import { Parser } from "${packageConfig.packageName === "prettier" ? "../index.js" : "prettier"}";
// Export available `parsers` and `printers` as types. If none are available,
// export an empty module object to ensure the file is treated as a module
const types = [];
const declarations = [];
if (parserNames.length > 0) {
types.push("Parser");
declarations.push(
outdent`
export declare const parsers: {
${parserNames
.map(
@@ -53,6 +57,33 @@ async function buildPluginTypes({ packageConfig, file: { input, output } }) {
)
.join("\n")}
};
`,
);
}
if (printerNames.length > 0) {
types.push("Printer");
declarations.push(
outdent`
export declare const printers: {
${printerNames
.map(
(printerName) =>
`${" ".repeat(2)}${toPropertyKey(printerName)}: Printer;`,
)
.join("\n")}
};
`,
);
}
const code =
declarations.length === 0
? "export {};"
: outdent`
import { ${types.join(", ")} } from "${typesImportPath}";
${declarations.join("\n\n")}
`;
await writeFile(
+4
View File
@@ -1,4 +1,5 @@
import * as prettier from "../../../../dist/prettier/index.js";
import { expectType } from "ts-expect";
import * as prettierPluginEstree from "../../../../dist/prettier/plugins/estree.js";
import * as prettierPluginBabel from "../../../../dist/prettier/plugins/babel.js";
@@ -104,3 +105,6 @@ prettier.format("hello world", {
prettierPluginYaml,
],
});
expectType<prettier.Printer>(prettierPluginEstree.printers.estree);
expectType<prettier.Printer>(prettierPluginEstree.printers["estree-json"]);