[babel 8] Type checking preset-typescript options (#12460)
* refactor: extract option normalization in preset-typescript * breaking: type checking preset-typescript options * chore: bundle preset-typescript into a single lib * test: disable Babel 7 test on Babel 8 breaking change test * workaround Jest 24 error snapshot dedent issue * skip Babel 8 test when the Breaking ENV is not available * chore: update test snapshot * Update packages/babel-preset-typescript/test/normalize-options.spec.js Co-authored-by: Nicolò Ribaudo <nicolo.ribaudo@gmail.com> * update test fixtures Co-authored-by: Nicolò Ribaudo <nicolo.ribaudo@gmail.com>
This commit is contained in:
parent
866a742bf7
commit
ff52acee79
@ -361,6 +361,7 @@ function copyDts(packages) {
|
||||
const libBundles = [
|
||||
"packages/babel-parser",
|
||||
"packages/babel-plugin-proposal-optional-chaining",
|
||||
"packages/babel-preset-typescript",
|
||||
"packages/babel-helper-member-expression-to-functions",
|
||||
].map(src => ({
|
||||
src,
|
||||
|
||||
@ -1,35 +1,19 @@
|
||||
import { declare } from "@babel/helper-plugin-utils";
|
||||
import transformTypeScript from "@babel/plugin-transform-typescript";
|
||||
import { OptionValidator } from "@babel/helper-validator-option";
|
||||
const v = new OptionValidator("@babel/preset-typescript");
|
||||
import normalizeOptions from "./normalize-options.js";
|
||||
|
||||
export default declare((api, opts) => {
|
||||
api.assertVersion(7);
|
||||
|
||||
const {
|
||||
allExtensions,
|
||||
allowDeclareFields,
|
||||
allowNamespaces,
|
||||
isTSX,
|
||||
jsxPragma,
|
||||
jsxPragmaFrag,
|
||||
onlyRemoveTypeImports,
|
||||
} = opts;
|
||||
|
||||
const jsxPragmaFrag = v.validateStringOption(
|
||||
"jsxPragmaFrag",
|
||||
opts.jsxPragmaFrag,
|
||||
"React.Fragment",
|
||||
);
|
||||
|
||||
const allExtensions = v.validateBooleanOption(
|
||||
"allExtensions",
|
||||
opts.allExtensions,
|
||||
false,
|
||||
);
|
||||
|
||||
const isTSX = v.validateBooleanOption("isTSX", opts.isTSX, false);
|
||||
|
||||
if (isTSX) {
|
||||
v.invariant(allExtensions, "isTSX:true requires allExtensions:true");
|
||||
}
|
||||
} = normalizeOptions(opts);
|
||||
|
||||
const pluginOptions = isTSX => ({
|
||||
allowDeclareFields,
|
||||
|
||||
72
packages/babel-preset-typescript/src/normalize-options.js
Normal file
72
packages/babel-preset-typescript/src/normalize-options.js
Normal file
@ -0,0 +1,72 @@
|
||||
import { OptionValidator } from "@babel/helper-validator-option";
|
||||
const v = new OptionValidator("@babel/preset-typescript");
|
||||
|
||||
export default function normalizeOptions(options = {}) {
|
||||
let {
|
||||
allowDeclareFields,
|
||||
allowNamespaces,
|
||||
jsxPragma,
|
||||
onlyRemoveTypeImports,
|
||||
} = options;
|
||||
|
||||
if (process.env.BABEL_8_BREAKING) {
|
||||
const TopLevelOptions = {
|
||||
allowDeclareFields: "allowDeclareFields",
|
||||
allExtensions: "allExtensions",
|
||||
allowNamespaces: "allowNamespaces",
|
||||
isTSX: "isTSX",
|
||||
jsxPragma: "jsxPragma",
|
||||
jsxPragmaFrag: "jsxPragmaFrag",
|
||||
onlyRemoveTypeImports: "onlyRemoveTypeImports",
|
||||
};
|
||||
v.validateTopLevelOptions(options, TopLevelOptions);
|
||||
allowDeclareFields = v.validateBooleanOption(
|
||||
TopLevelOptions.allowDeclareFields,
|
||||
options.allowDeclareFields,
|
||||
true,
|
||||
);
|
||||
allowNamespaces = v.validateBooleanOption(
|
||||
TopLevelOptions.allowNamespaces,
|
||||
options.allowNamespaces,
|
||||
true,
|
||||
);
|
||||
jsxPragma = v.validateStringOption(
|
||||
TopLevelOptions.jsxPragma,
|
||||
options.jsxPragma,
|
||||
"React",
|
||||
);
|
||||
onlyRemoveTypeImports = v.validateBooleanOption(
|
||||
TopLevelOptions.onlyRemoveTypeImports,
|
||||
options.onlyRemoveTypeImports,
|
||||
true,
|
||||
);
|
||||
}
|
||||
|
||||
const jsxPragmaFrag = v.validateStringOption(
|
||||
"jsxPragmaFrag",
|
||||
options.jsxPragmaFrag,
|
||||
"React.Fragment",
|
||||
);
|
||||
|
||||
const allExtensions = v.validateBooleanOption(
|
||||
"allExtensions",
|
||||
options.allExtensions,
|
||||
false,
|
||||
);
|
||||
|
||||
const isTSX = v.validateBooleanOption("isTSX", options.isTSX, false);
|
||||
|
||||
if (isTSX) {
|
||||
v.invariant(allExtensions, "isTSX:true requires allExtensions:true");
|
||||
}
|
||||
|
||||
return {
|
||||
allExtensions,
|
||||
allowDeclareFields,
|
||||
allowNamespaces,
|
||||
isTSX,
|
||||
jsxPragma,
|
||||
jsxPragmaFrag,
|
||||
onlyRemoveTypeImports,
|
||||
};
|
||||
}
|
||||
@ -0,0 +1,93 @@
|
||||
import normalizeOptions from "../src/normalize-options";
|
||||
describe("normalize options", () => {
|
||||
(process.env.BABEL_8_BREAKING ? describe : describe.skip)("Babel 8", () => {
|
||||
it("should throw on unknown options", () => {
|
||||
expect(() => normalizeOptions({ allowNamespace: true })).toThrowError(
|
||||
"@babel/preset-typescript: 'allowNamespace' is not a valid top-level option.\n- Did you mean 'allowNamespaces'?",
|
||||
);
|
||||
});
|
||||
it.each([
|
||||
"allowDeclareFields",
|
||||
"allExtensions",
|
||||
"allowNamespaces",
|
||||
"isTSX",
|
||||
"onlyRemoveTypeImports",
|
||||
])("should throw when `%p` is not a boolean", optionName => {
|
||||
expect(() => normalizeOptions({ [optionName]: 0 })).toThrow(
|
||||
`@babel/preset-typescript: '${optionName}' option must be a boolean.`,
|
||||
);
|
||||
});
|
||||
it.each(["jsxPragma", "jsxPragmaFrag"])(
|
||||
"should throw when `%p` is not a string",
|
||||
optionName => {
|
||||
expect(() => normalizeOptions({ [optionName]: 0 })).toThrow(
|
||||
`@babel/preset-typescript: '${optionName}' option must be a string.`,
|
||||
);
|
||||
},
|
||||
);
|
||||
it("should not throw when options is not defined", () => {
|
||||
expect(() => normalizeOptions()).not.toThrowError();
|
||||
});
|
||||
it("default values", () => {
|
||||
expect(normalizeOptions({})).toMatchInlineSnapshot(`
|
||||
Object {
|
||||
"allExtensions": false,
|
||||
"allowDeclareFields": true,
|
||||
"allowNamespaces": true,
|
||||
"isTSX": false,
|
||||
"jsxPragma": "React",
|
||||
"jsxPragmaFrag": "React.Fragment",
|
||||
"onlyRemoveTypeImports": true,
|
||||
}
|
||||
`);
|
||||
});
|
||||
});
|
||||
(process.env.BABEL_8_BREAKING ? describe.skip : describe)("Babel 7", () => {
|
||||
it("should not throw on unknown options", () => {
|
||||
expect(() =>
|
||||
normalizeOptions({ allowNamespace: true }),
|
||||
).not.toThrowError();
|
||||
});
|
||||
it.each(["allowDeclareFields", "allowNamespaces", "onlyRemoveTypeImports"])(
|
||||
"should not throw when `%p` is not a boolean",
|
||||
optionName => {
|
||||
expect(() => normalizeOptions({ [optionName]: 0 })).not.toThrowError();
|
||||
},
|
||||
);
|
||||
it.each(["jsxPragma"])(
|
||||
"should throw when `%p` is not a string",
|
||||
optionName => {
|
||||
expect(() => normalizeOptions({ [optionName]: 0 })).not.toThrowError();
|
||||
},
|
||||
);
|
||||
it.each(["allExtensions", "isTSX"])(
|
||||
"should throw when `%p` is not a boolean",
|
||||
optionName => {
|
||||
expect(() => normalizeOptions({ [optionName]: 0 })).toThrow(
|
||||
`@babel/preset-typescript: '${optionName}' option must be a boolean.`,
|
||||
);
|
||||
},
|
||||
);
|
||||
it.each(["jsxPragmaFrag"])(
|
||||
"should throw when `%p` is not a string",
|
||||
optionName => {
|
||||
expect(() => normalizeOptions({ [optionName]: 0 })).toThrow(
|
||||
`@babel/preset-typescript: '${optionName}' option must be a string.`,
|
||||
);
|
||||
},
|
||||
);
|
||||
it("default values", () => {
|
||||
expect(normalizeOptions({})).toMatchInlineSnapshot(`
|
||||
Object {
|
||||
"allExtensions": false,
|
||||
"allowDeclareFields": undefined,
|
||||
"allowNamespaces": undefined,
|
||||
"isTSX": false,
|
||||
"jsxPragma": undefined,
|
||||
"jsxPragmaFrag": "React.Fragment",
|
||||
"onlyRemoveTypeImports": undefined,
|
||||
}
|
||||
`);
|
||||
});
|
||||
});
|
||||
});
|
||||
Loading…
x
Reference in New Issue
Block a user