Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve transform-runtime typings #14605

Merged
merged 4 commits into from May 26, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
@@ -1,6 +1,7 @@
import syntaxObjectRestSpread from "@babel/plugin-syntax-object-rest-spread";
import type { PluginAPI, PluginObject } from "@babel/core";

export default function ({ types: t }) {
export default function ({ types: t }: PluginAPI): PluginObject {
return {
inherits: syntaxObjectRestSpread.default,

Expand All @@ -21,10 +22,15 @@ export default function ({ types: t }) {
const arg = args[i];
const { node } = arg;

if (arg.isObjectExpression()) {
if (t.isObjectExpression(node)) {
properties.push(...node.properties);
} else {
properties.push(t.spreadElement(node));
properties.push(
t.spreadElement(
// @ts-expect-error fixme
node,
),
);
}
}

Expand Down
@@ -1,6 +1,7 @@
import syntaxOptionalCatchBinding from "@babel/plugin-syntax-optional-catch-binding";
import type { PluginAPI, PluginObject } from "@babel/core";

export default function ({ types: t }) {
export default function ({ types: t }: PluginAPI): PluginObject {
return {
inherits: syntaxOptionalCatchBinding.default,

Expand Down
5 changes: 4 additions & 1 deletion packages/babel-core/src/config/index.ts
Expand Up @@ -18,7 +18,10 @@ type PluginAPI = basePluginAPI & typeof import("..");
type PresetAPI = basePresetAPI & typeof import("..");
export type { PluginAPI, PresetAPI };
// todo: may need to refine PresetObject to be a subset of ValidatedOptions
export type { ValidatedOptions as PresetObject } from "./validation/options";
export type {
CallerMetadata,
ValidatedOptions as PresetObject,
} from "./validation/options";

import loadFullConfig from "./full";
import { loadPartialConfig as loadPartialConfigRunner } from "./partial";
Expand Down
2 changes: 2 additions & 0 deletions packages/babel-core/src/index.ts
Expand Up @@ -30,6 +30,8 @@ export {
} from "./config";

export type {
CallerMetadata,
InputOptions,
PluginAPI,
PluginObject,
PresetAPI,
Expand Down
@@ -1,4 +1,8 @@
export default function (moduleName, dirname, absoluteRuntime) {
export default function (
moduleName: string,
dirname: string,
absoluteRuntime: string | boolean,
) {
if (absoluteRuntime === false) return moduleName;

resolveFSPath();
Expand Down
Expand Up @@ -3,7 +3,11 @@ import path from "path";
import { createRequire } from "module";
const require = createRequire(import.meta.url);

export default function (moduleName, dirname, absoluteRuntime) {
export default function (
moduleName: string,
dirname: string,
absoluteRuntime: string | boolean,
) {
if (absoluteRuntime === false) return moduleName;

return resolveAbsoluteRuntime(
Expand Down Expand Up @@ -33,6 +37,6 @@ function resolveAbsoluteRuntime(moduleName: string, dirname: string) {
}
}

export function resolveFSPath(path) {
export function resolveFSPath(path: string) {
return require.resolve(path).replace(/\\/g, "/");
}
5 changes: 4 additions & 1 deletion packages/babel-plugin-transform-runtime/src/helpers.ts
@@ -1,6 +1,9 @@
import semver from "semver";

export function hasMinVersion(minVersion, runtimeVersion) {
export function hasMinVersion(
minVersion: string,
runtimeVersion: string | void,
) {
// If the range is unavailable, we're running the script during Babel's
// build process, and we want to assume that all versions are satisfied so
// that the built output will include all definitions.
Expand Down
73 changes: 62 additions & 11 deletions packages/babel-plugin-transform-runtime/src/index.ts
Expand Up @@ -4,6 +4,7 @@ import { types as t } from "@babel/core";

import { hasMinVersion } from "./helpers";
import getRuntimePath, { resolveFSPath } from "./get-runtime-path";
import type { PluginAPI, PluginObject, CallerMetadata } from "@babel/core";

import _pluginCorejs2 from "babel-plugin-polyfill-corejs2";
import _pluginCorejs3 from "babel-plugin-polyfill-corejs3";
Expand All @@ -17,7 +18,8 @@ const pluginRegenerator = (_pluginRegenerator.default ||

const pluginsCompat = "#__secret_key__@babel/runtime__compatibility";

function supportsStaticESM(caller) {
function supportsStaticESM(caller: CallerMetadata | void) {
// @ts-ignore TS does not narrow down optional chaining
return !!caller?.supportsStaticESM;
}

Expand All @@ -30,6 +32,35 @@ export interface Options {
version?: string;
}

interface CoreJS2PluginOptions {
absoluteImports: string | false;
method: "usage-pure";
[pluginsCompat]: {
runtimeVersion: string;
useBabelRuntime: string | false;
ext: string;
};
}

interface RegeneratorPluginOptions {
absoluteImports: string | false;
method: "usage-pure";
[pluginsCompat]: {
useBabelRuntime: string | false;
};
}

interface CoreJS3PluginOptions {
absoluteImports: string | false;
method: "usage-pure";
proposals: boolean;
version: number;
[pluginsCompat]: {
useBabelRuntime: string | false;
ext: string;
};
}

export default declare((api, options: Options, dirname) => {
api.assertVersion(7);

Expand Down Expand Up @@ -106,11 +137,12 @@ export default declare((api, options: Options, dirname) => {
var supportsCJSDefault = hasMinVersion(DUAL_MODE_RUNTIME, runtimeVersion);
}

function has(obj, key) {
function has(obj: {}, key: string) {
return Object.prototype.hasOwnProperty.call(obj, key);
}

if (has(options, "useBuiltIns")) {
// @ts-expect-error deprecated options
if (options["useBuiltIns"]) {
throw new Error(
"The 'useBuiltIns' option has been removed. The @babel/runtime " +
Expand All @@ -125,6 +157,7 @@ export default declare((api, options: Options, dirname) => {
}

if (has(options, "polyfill")) {
// @ts-expect-error deprecated options
if (options["polyfill"] === false) {
throw new Error(
"The 'polyfill' option has been removed. The @babel/runtime " +
Expand Down Expand Up @@ -163,8 +196,20 @@ export default declare((api, options: Options, dirname) => {

const modulePath = getRuntimePath(moduleName, dirname, absoluteRuntime);

function createCorejsPlgin(plugin, options, regeneratorPlugin) {
return (api, _, filename) => {
function createCorejsPlgin<Options extends {}>(
plugin: (
api: PluginAPI,
options: Options,
filename: string,
) => PluginObject,
options: Options,
regeneratorPlugin: (
api: PluginAPI,
options: RegeneratorPluginOptions,
filename: string,
) => PluginObject,
): (api: PluginAPI, options: {}, filename: string) => PluginObject {
return (api: PluginAPI, _: {}, filename: string) => {
return {
...plugin(api, options, filename),
inherits: regeneratorPlugin,
Expand All @@ -173,7 +218,13 @@ export default declare((api, options: Options, dirname) => {
}

// TODO: Remove this in Babel 8
function createRegeneratorPlugin(options) {
function createRegeneratorPlugin(
options: RegeneratorPluginOptions,
): (
api: PluginAPI,
options: RegeneratorPluginOptions,
filename: string,
) => PluginObject {
if (!useRuntimeRegenerator) return undefined;
return (api, _, filename) => {
return pluginRegenerator(api, options, filename);
Expand All @@ -184,7 +235,7 @@ export default declare((api, options: Options, dirname) => {
name: "transform-runtime",

inherits: injectCoreJS2
? createCorejsPlgin(
? createCorejsPlgin<CoreJS2PluginOptions>(
pluginCorejs2,
{
method: "usage-pure",
Expand All @@ -202,7 +253,7 @@ export default declare((api, options: Options, dirname) => {
}),
)
: injectCoreJS3
? createCorejsPlgin(
? createCorejsPlgin<CoreJS3PluginOptions>(
pluginCorejs3,
{
method: "usage-pure",
Expand All @@ -226,7 +277,7 @@ export default declare((api, options: Options, dirname) => {
pre(file) {
if (!useRuntimeHelpers) return;

file.set("helperGenerator", name => {
file.set("helperGenerator", (name: string) => {
// If the helper didn't exist yet at the version given, we bail
// out and let Babel either insert it directly, or throw an error
// so that plugins can handle that case properly.
Expand Down Expand Up @@ -271,9 +322,9 @@ export default declare((api, options: Options, dirname) => {
const cache = new Map();

function addDefaultImport(
source,
nameHint,
blockHoist,
source: string,
nameHint: string,
blockHoist: number,
isHelper = false,
) {
// If something on the page adds a helper when the file is an ES6
Expand Down
10 changes: 5 additions & 5 deletions packages/babel-plugin-transform-typescript/src/enum.ts
Expand Up @@ -39,7 +39,7 @@ export default function transpileEnum(
throw new Error(`Unexpected enum parent '${path.parent.type}`);
}

function seen(parentPath: NodePath<t.Node>) {
function seen(parentPath: NodePath<t.Node>): boolean {
if (parentPath.isExportDeclaration()) {
return seen(parentPath.parentPath);
}
Expand Down Expand Up @@ -193,12 +193,12 @@ export function translateEnumValues(

// Based on the TypeScript repository's `evalConstant` in `checker.ts`.
function evaluate(
expr,
expr: t.Node,
seen: PreviousEnumMembers,
): number | string | typeof undefined {
return evalConstant(expr);

function evalConstant(expr): number | typeof undefined {
function evalConstant(expr: t.Node): number | typeof undefined {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a same thing

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah. I am good to leave it as-is. I can open a new PR replacing typeof undefined to undefined later.

switch (expr.type) {
case "StringLiteral":
return expr.value;
Expand All @@ -225,7 +225,7 @@ function evaluate(
function evalUnaryExpression({
argument,
operator,
}): number | typeof undefined {
}: t.UnaryExpression): number | typeof undefined {
const value = evalConstant(argument);
if (value === undefined) {
return undefined;
Expand All @@ -243,7 +243,7 @@ function evaluate(
}
}

function evalBinaryExpression(expr): number | typeof undefined {
function evalBinaryExpression(expr: t.BinaryExpression): number | undefined {
const left = evalConstant(expr.left);
if (left === undefined) {
return undefined;
Expand Down
23 changes: 17 additions & 6 deletions packages/babel-plugin-transform-typescript/src/index.ts
Expand Up @@ -2,7 +2,7 @@ import { declare } from "@babel/helper-plugin-utils";
import syntaxTypeScript from "@babel/plugin-syntax-typescript";
import { types as t, template } from "@babel/core";
import { injectInitialization } from "@babel/helper-create-class-features-plugin";
import type { NodePath } from "@babel/traverse";
import type { Binding, NodePath } from "@babel/traverse";
import type { Options as SyntaxOptions } from "@babel/plugin-syntax-typescript";

import transpileConstEnum from "./const-enum";
Expand Down Expand Up @@ -149,15 +149,15 @@ export default declare((api, opts: Options) => {
if (node.declare) node.declare = null;
if (node.override) node.override = null;
},
method({ node }) {
method({ node }: NodePath<t.ClassMethod | t.ClassPrivateMethod>) {
if (node.accessibility) node.accessibility = null;
if (node.abstract) node.abstract = null;
if (node.optional) node.optional = null;
if (node.override) node.override = null;

// Rest handled by Function visitor
},
constructor(path, classPath) {
constructor(path: NodePath<t.ClassMethod>, classPath: NodePath<t.Class>) {
if (path.node.accessibility) path.node.accessibility = null;
// Collects parameter properties so that we can add an assignment
// for each of them in the constructor body
Expand Down Expand Up @@ -487,7 +487,11 @@ export default declare((api, opts: Options) => {
path.get("body.body").forEach(child => {
if (child.isClassMethod() || child.isClassPrivateMethod()) {
if (child.node.kind === "constructor") {
classMemberVisitors.constructor(child, path);
classMemberVisitors.constructor(
// @ts-expect-error A constructor must not be a private method
child,
path,
);
} else {
classMemberVisitors.method(child);
}
Expand All @@ -512,7 +516,7 @@ export default declare((api, opts: Options) => {
},

TSModuleDeclaration(path) {
transpileNamespace(path, t, allowNamespaces);
transpileNamespace(path, allowNamespaces);
},

TSInterfaceDeclaration(path) {
Expand Down Expand Up @@ -614,7 +618,9 @@ export default declare((api, opts: Options) => {
return node;
}

function visitPattern({ node }) {
function visitPattern({
node,
}: NodePath<t.Identifier | t.Pattern | t.RestElement>) {
if (node.typeAnnotation) node.typeAnnotation = null;
if (t.isIdentifier(node) && node.optional) node.optional = null;
// 'access' and 'readonly' are only for parameter properties, so constructor visitor will handle them.
Expand All @@ -625,6 +631,11 @@ export default declare((api, opts: Options) => {
programPath,
pragmaImportName,
pragmaFragImportName,
}: {
binding: Binding;
programPath: NodePath<t.Program>;
pragmaImportName: string;
pragmaFragImportName: string;
}) {
for (const path of binding.referencePaths) {
if (!isInType(path)) {
Expand Down