Skip to content

Commit 57f702f

Browse files
poradafisker
andcommitted
Include available printers in plugin type declarations (#18706)
Co-authored-by: fisker <[email protected]>
1 parent bece827 commit 57f702f

3 files changed

Lines changed: 57 additions & 7 deletions

File tree

changelog_unreleased/api/18706.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#### Include available `printers` in plugin type declarations (#18706 by @porada)
2+
3+
<!-- prettier-ignore -->
4+
```ts
5+
// Input
6+
import * as prettierPluginEstree from "prettier/plugins/estree";
7+
8+
// Prettier stable
9+
// Property 'printers' does not exist on type 'typeof import("prettier/plugins/estree")'. ts(2339)
10+
prettierPluginEstree.printers.estree; //=> any
11+
12+
// Prettier main
13+
prettierPluginEstree.printers.estree; //=> Printer
14+
prettierPluginEstree.printers["estree-json"]; //=> Printer
15+
```

scripts/build/build-types.js

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,19 @@ async function buildPluginTypes({ packageConfig, file: { input, output } }) {
3636
);
3737
const plugin = pluginModule.default ?? pluginModule;
3838
const parserNames = Object.keys(plugin.parsers ?? {});
39+
const printerNames = Object.keys(plugin.printers ?? {});
40+
const typesImportPath =
41+
packageConfig.packageName === "prettier" ? "../index.js" : "prettier";
3942

40-
// We only add `parsers` to types file, printers should not be used alone
41-
// For `estree` plugin, we just export an empty object to ensure it treated as a module
42-
const code =
43-
parserNames.length === 0
44-
? "export {};"
45-
: outdent`
46-
import { Parser } from "${packageConfig.packageName === "prettier" ? "../index.js" : "prettier"}";
43+
// Export available `parsers` and `printers` as types. If none are available,
44+
// export an empty module object to ensure the file is treated as a module
45+
const types = [];
46+
const declarations = [];
4747

48+
if (parserNames.length > 0) {
49+
types.push("Parser");
50+
declarations.push(
51+
outdent`
4852
export declare const parsers: {
4953
${parserNames
5054
.map(
@@ -53,6 +57,33 @@ async function buildPluginTypes({ packageConfig, file: { input, output } }) {
5357
)
5458
.join("\n")}
5559
};
60+
`,
61+
);
62+
}
63+
64+
if (printerNames.length > 0) {
65+
types.push("Printer");
66+
declarations.push(
67+
outdent`
68+
export declare const printers: {
69+
${printerNames
70+
.map(
71+
(printerName) =>
72+
`${" ".repeat(2)}${toPropertyKey(printerName)}: Printer;`,
73+
)
74+
.join("\n")}
75+
};
76+
`,
77+
);
78+
}
79+
80+
const code =
81+
declarations.length === 0
82+
? "export {};"
83+
: outdent`
84+
import { ${types.join(", ")} } from "${typesImportPath}";
85+
86+
${declarations.join("\n\n")}
5687
`;
5788

5889
await writeFile(

tests/dts/unit/cases/parsers.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import * as prettier from "../../../../dist/prettier/index.js";
2+
import { expectType } from "ts-expect";
23

34
import * as prettierPluginEstree from "../../../../dist/prettier/plugins/estree.js";
45
import * as prettierPluginBabel from "../../../../dist/prettier/plugins/babel.js";
@@ -104,3 +105,6 @@ prettier.format("hello world", {
104105
prettierPluginYaml,
105106
],
106107
});
108+
109+
expectType<prettier.Printer>(prettierPluginEstree.printers.estree);
110+
expectType<prettier.Printer>(prettierPluginEstree.printers["estree-json"]);

0 commit comments

Comments
 (0)