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

[parser] Improve getPluginOptions type #14861

Merged
merged 1 commit into from Aug 18, 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
15 changes: 12 additions & 3 deletions packages/babel-parser/src/parser/base.ts
Expand Up @@ -5,7 +5,11 @@ import type ScopeHandler from "../util/scope";
import type ExpressionScopeHandler from "../util/expression-scope";
import type ClassScopeHandler from "../util/class-scope";
import type ProductionParameterHandler from "../util/production-parameter";
import type { PluginConfig } from "../typings";
import type {
ParserPluginWithOptions,
PluginConfig,
PluginOptions,
} from "../typings";

export default class BaseParser {
// Properties set by constructor in index.js
Expand Down Expand Up @@ -54,7 +58,12 @@ export default class BaseParser {
}
}

getPluginOption(plugin: string, name: string) {
return this.plugins.get(plugin)?.[name];
getPluginOption<
PluginName extends ParserPluginWithOptions[0],
OptionName extends keyof PluginOptions<PluginName>,
>(plugin: PluginName, name: OptionName) {
return (this.plugins.get(plugin) as null | PluginOptions<PluginName>)?.[
name
];
}
}
20 changes: 11 additions & 9 deletions packages/babel-parser/src/plugin-utils.ts
@@ -1,5 +1,9 @@
import type Parser from "./parser";
import type { PluginConfig } from "./typings";
import type {
ParserPluginWithOptions,
PluginConfig,
PluginOptions,
} from "./typings";

export type Plugin = PluginConfig;

Expand Down Expand Up @@ -47,11 +51,10 @@ export function hasPlugin(
});
}

export function getPluginOption(
plugins: PluginList,
name: string,
option: string,
) {
export function getPluginOption<
PluginName extends ParserPluginWithOptions[0],
OptionName extends keyof PluginOptions<PluginName>,
>(plugins: PluginList, name: PluginName, option: OptionName) {
const plugin = plugins.find(plugin => {
if (Array.isArray(plugin)) {
return plugin[0] === name;
Expand All @@ -60,9 +63,8 @@ export function getPluginOption(
}
});

if (plugin && Array.isArray(plugin)) {
// @ts-expect-error Fixme: should check whether option is defined
return plugin[1][option];
if (plugin && Array.isArray(plugin) && plugin.length > 1) {
return (plugin[1] as PluginOptions<PluginName>)[option];
}

return null;
Expand Down
20 changes: 10 additions & 10 deletions packages/babel-parser/src/typings.ts
Expand Up @@ -7,13 +7,11 @@ export type Plugin =
| "classProperties"
| "classStaticBlock" // Enabled by default
| "decimal"
| "decorators"
| "decorators-legacy"
| "decoratorAutoAccessors"
| "destructuringPrivate"
| "doExpressions"
| "dynamicImport"
| "estree"
| "exportDefaultFrom"
| "exportNamespaceFrom" // deprecated
| "flow"
Expand All @@ -24,8 +22,6 @@ export type Plugin =
| "jsx"
| "logicalAssignment"
| "importAssertions"
// @deprecated
| "moduleAttributes"
| "moduleBlocks"
| "moduleStringNames"
| "nullishCoalescingOperator"
Expand All @@ -34,25 +30,29 @@ export type Plugin =
| "optionalCatchBinding"
| "optionalChaining"
| "partialApplication"
| "pipelineOperator"
| "placeholders"
| "privateIn" // Enabled by default
| "recordAndTuple"
| "regexpUnicodeSets"
| "throwExpressions"
| "topLevelAwait"
| "typescript"
| "v8intrinsic";

export type PluginConfig = Plugin | ParserPluginWithOptions;
| "v8intrinsic"
| ParserPluginWithOptions[0];

export type ParserPluginWithOptions =
| ["decorators", DecoratorsPluginOptions]
| ["estree", { classFeatures?: boolean }]
// @deprecated
| ["moduleAttributes", { version: "may-2020" }]
| ["pipelineOperator", PipelineOperatorPluginOptions]
| ["recordAndTuple", RecordAndTuplePluginOptions]
| ["flow", FlowPluginOptions]
| ["typescript", TypeScriptPluginOptions];

export type PluginConfig = Plugin | ParserPluginWithOptions;

export type PluginOptions<PluginName extends ParserPluginWithOptions[0]> =
Extract<ParserPluginWithOptions, [PluginName, any]>[1];

export interface DecoratorsPluginOptions {
decoratorsBeforeExport?: boolean;
}
Expand Down