Skip to content

Commit

Permalink
Use .ts files with explicit re-exports to solve builder conflicts
Browse files Browse the repository at this point in the history
  • Loading branch information
nicolo-ribaudo committed Feb 12, 2025
1 parent 99d89fc commit 5171a71
Show file tree
Hide file tree
Showing 7 changed files with 3,516 additions and 3,471 deletions.
3 changes: 2 additions & 1 deletion Gulpfile.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -768,8 +768,9 @@ gulp.task("generate-type-helpers", () => {

return Promise.all([
generateTypeHelpers("asserts"),
generateTypeHelpers("builders", "lowercase.ts"),
generateTypeHelpers("builders", "uppercase.ts"),
generateTypeHelpers("builders"),
generateTypeHelpers("builders", "uppercase.js"),
generateTypeHelpers("constants"),
generateTypeHelpers("validators"),
generateTypeHelpers("ast-types"),
Expand Down
50 changes: 40 additions & 10 deletions packages/babel-types/scripts/generators/builders.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,11 @@ function generateBuilderArgs(type) {
}

export default function generateBuilders(kind) {
return kind === "uppercase.js"
? generateUppercaseBuilders()
: generateLowercaseBuilders();
return kind === "lowercase.ts"
? generateLowercaseBuilders()
: kind === "uppercase.ts"
? generateUppercaseBuilders()
: generateBuildersAndAstTypesReexports();
}

function generateLowercaseBuilders() {
Expand All @@ -98,7 +100,7 @@ function generateLowercaseBuilders() {
* To re-generate run 'make build'
*/
import * as _validate from "../../validators/validate.ts";
import type * as t from "../../index.ts";
import type * as t from "../../ast-types/generated/index.ts";
import deprecationWarning from "../../utils/deprecationWarning.ts";
import * as utils from "../../definitions/utils.ts";
Expand Down Expand Up @@ -204,11 +206,6 @@ function generateUppercaseBuilders() {
* To re-generate run 'make build'
*/
/**
* This file is written in JavaScript and not TypeScript because uppercase builders
* conflict with AST types. TypeScript reads the uppercase.d.ts file instead.
*/
export {\n`;

Object.keys(BUILDER_KEYS).forEach(type => {
Expand All @@ -221,6 +218,39 @@ function generateUppercaseBuilders() {
output += ` ${formattedBuilderName} as ${type},\n`;
});

output += ` } from './index.ts';\n`;
output += ` } from './lowercase.ts';\n`;
return output;
}

function generateBuildersAndAstTypesReexports() {
return `/*
* This file is auto-generated! Do not modify it directly.
* To re-generate run 'make build'
*/
export * from "./lowercase.ts";
export * from "./uppercase.ts";
// Uppercase builders and AST types conflict with each other, which is
// not allowed by TypeScript when using \`export * from ...\`
// We instead explicity list the AST types here, so that:
// - From a TypeScript perspective, the AST types win over the uppercase
// builders (which is the standard behavior for JS when a named
// re-export conflicts with a * re-export.)
// - At runtime, this \`export type\` is removed, leaving only the uppercase
// builders behind (which are thus visible to JavaScript code).
// This ensures compatibility with legacy code that uses the uppercase
// builders, while allowing TypeScript users to use the lowercase builders
// together with the AST types.
// prettier-ignore
export type {
${Object.keys(BUILDER_KEYS).join(", ")},
${Object.keys(DEPRECATED_KEYS).join(", ")}
} from "../../ast-types/generated/index.ts";
// This will re-export all the type definitions that do not conflict with
// uppercase builders, such as aliases.
export type * from "../../ast-types/generated/index.ts";
`;
}
Loading

0 comments on commit 5171a71

Please sign in to comment.