improve node type definitions to avoid any's in generated types (#11687)
This commit is contained in:
parent
4108524856
commit
36f9798f42
@ -84,10 +84,13 @@ defineType("BinaryExpression", {
|
||||
const expression = assertNodeType("Expression");
|
||||
const inOp = assertNodeType("Expression", "PrivateName");
|
||||
|
||||
return function (node, key, val) {
|
||||
const validator = function (node, key, val) {
|
||||
const validator = node.operator === "in" ? inOp : expression;
|
||||
validator(node, key, val);
|
||||
};
|
||||
// todo(ts): can be discriminated union by `operator` property
|
||||
validator.oneOfNodeTypes = ["Expression", "PrivateName"];
|
||||
return validator;
|
||||
})(),
|
||||
},
|
||||
right: {
|
||||
@ -276,6 +279,15 @@ defineType("File", {
|
||||
program: {
|
||||
validate: assertNodeType("Program"),
|
||||
},
|
||||
comments: {
|
||||
validate: assertEach(assertNodeType("Comment")),
|
||||
optional: true,
|
||||
},
|
||||
tokens: {
|
||||
// todo(ts): add Token type
|
||||
validate: assertEach(Object.assign(() => {}, { type: "any" })),
|
||||
optional: true,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@ -457,13 +469,19 @@ defineType("Identifier", {
|
||||
fields: {
|
||||
...patternLikeCommon,
|
||||
name: {
|
||||
validate: chain(assertValueType("string"), function (node, key, val) {
|
||||
if (!process.env.BABEL_TYPES_8_BREAKING) return;
|
||||
validate: chain(
|
||||
assertValueType("string"),
|
||||
Object.assign(
|
||||
function (node, key, val) {
|
||||
if (!process.env.BABEL_TYPES_8_BREAKING) return;
|
||||
|
||||
if (!isValidIdentifier(val, false)) {
|
||||
throw new TypeError(`"${val}" is not a valid identifier name`);
|
||||
}
|
||||
}),
|
||||
if (!isValidIdentifier(val, false)) {
|
||||
throw new TypeError(`"${val}" is not a valid identifier name`);
|
||||
}
|
||||
},
|
||||
{ type: "string" },
|
||||
),
|
||||
),
|
||||
},
|
||||
optional: {
|
||||
validate: assertValueType("boolean"),
|
||||
@ -583,14 +601,20 @@ defineType("RegExpLiteral", {
|
||||
validate: assertValueType("string"),
|
||||
},
|
||||
flags: {
|
||||
validate: chain(assertValueType("string"), function (node, key, val) {
|
||||
if (!process.env.BABEL_TYPES_8_BREAKING) return;
|
||||
validate: chain(
|
||||
assertValueType("string"),
|
||||
Object.assign(
|
||||
function (node, key, val) {
|
||||
if (!process.env.BABEL_TYPES_8_BREAKING) return;
|
||||
|
||||
const invalid = /[^gimsuy]/.exec(val);
|
||||
if (invalid) {
|
||||
throw new TypeError(`"${invalid[0]}" is not a valid RegExp flag`);
|
||||
}
|
||||
}),
|
||||
const invalid = /[^gimsuy]/.exec(val);
|
||||
if (invalid) {
|
||||
throw new TypeError(`"${invalid[0]}" is not a valid RegExp flag`);
|
||||
}
|
||||
},
|
||||
{ type: "string" },
|
||||
),
|
||||
),
|
||||
default: "",
|
||||
},
|
||||
},
|
||||
@ -626,10 +650,13 @@ defineType("MemberExpression", {
|
||||
const normal = assertNodeType("Identifier", "PrivateName");
|
||||
const computed = assertNodeType("Expression");
|
||||
|
||||
return function (node, key, val) {
|
||||
const validator = function (node, key, val) {
|
||||
const validator = node.computed ? computed : normal;
|
||||
validator(node, key, val);
|
||||
};
|
||||
// todo(ts): can be discriminated union by `computed` property
|
||||
validator.oneOfNodeTypes = ["Expression", "Identifier", "PrivateName"];
|
||||
return validator;
|
||||
})(),
|
||||
},
|
||||
computed: {
|
||||
@ -719,10 +746,18 @@ defineType("ObjectMethod", {
|
||||
);
|
||||
const computed = assertNodeType("Expression");
|
||||
|
||||
return function (node, key, val) {
|
||||
const validator = function (node, key, val) {
|
||||
const validator = node.computed ? computed : normal;
|
||||
validator(node, key, val);
|
||||
};
|
||||
// todo(ts): can be discriminated union by `computed` property
|
||||
validator.oneOfNodeTypes = [
|
||||
"Expression",
|
||||
"Identifier",
|
||||
"StringLiteral",
|
||||
"NumericLiteral",
|
||||
];
|
||||
return validator;
|
||||
})(),
|
||||
},
|
||||
decorators: {
|
||||
@ -776,10 +811,18 @@ defineType("ObjectProperty", {
|
||||
);
|
||||
const computed = assertNodeType("Expression");
|
||||
|
||||
return function (node, key, val) {
|
||||
const validator = function (node, key, val) {
|
||||
const validator = node.computed ? computed : normal;
|
||||
validator(node, key, val);
|
||||
};
|
||||
// todo(ts): can be discriminated union by `computed` property
|
||||
validator.oneOfNodeTypes = [
|
||||
"Expression",
|
||||
"Identifier",
|
||||
"StringLiteral",
|
||||
"NumericLiteral",
|
||||
];
|
||||
return validator;
|
||||
})(),
|
||||
},
|
||||
value: {
|
||||
@ -790,15 +833,18 @@ defineType("ObjectProperty", {
|
||||
shorthand: {
|
||||
validate: chain(
|
||||
assertValueType("boolean"),
|
||||
function (node, key, val) {
|
||||
if (!process.env.BABEL_TYPES_8_BREAKING) return;
|
||||
Object.assign(
|
||||
function (node, key, val) {
|
||||
if (!process.env.BABEL_TYPES_8_BREAKING) return;
|
||||
|
||||
if (val && node.computed) {
|
||||
throw new TypeError(
|
||||
"Property shorthand of ObjectProperty cannot be true if computed is true",
|
||||
);
|
||||
}
|
||||
},
|
||||
if (val && node.computed) {
|
||||
throw new TypeError(
|
||||
"Property shorthand of ObjectProperty cannot be true if computed is true",
|
||||
);
|
||||
}
|
||||
},
|
||||
{ type: "boolean" },
|
||||
),
|
||||
function (node, key, val) {
|
||||
if (!process.env.BABEL_TYPES_8_BREAKING) return;
|
||||
|
||||
@ -945,18 +991,26 @@ defineType("TryStatement", {
|
||||
aliases: ["Statement"],
|
||||
fields: {
|
||||
block: {
|
||||
validate: chain(assertNodeType("BlockStatement"), function (node) {
|
||||
if (!process.env.BABEL_TYPES_8_BREAKING) return;
|
||||
validate: chain(
|
||||
assertNodeType("BlockStatement"),
|
||||
Object.assign(
|
||||
function (node) {
|
||||
if (!process.env.BABEL_TYPES_8_BREAKING) return;
|
||||
|
||||
// This validator isn't put at the top level because we can run it
|
||||
// even if this node doesn't have a parent.
|
||||
// This validator isn't put at the top level because we can run it
|
||||
// even if this node doesn't have a parent.
|
||||
|
||||
if (!node.handler && !node.finalizer) {
|
||||
throw new TypeError(
|
||||
"TryStatement expects either a handler or finalizer, or both",
|
||||
);
|
||||
}
|
||||
}),
|
||||
if (!node.handler && !node.finalizer) {
|
||||
throw new TypeError(
|
||||
"TryStatement expects either a handler or finalizer, or both",
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
oneOfNodeTypes: ["BlockStatement"],
|
||||
},
|
||||
),
|
||||
),
|
||||
},
|
||||
handler: {
|
||||
optional: true,
|
||||
|
||||
@ -170,6 +170,10 @@ defineType("ClassExpression", {
|
||||
),
|
||||
optional: true,
|
||||
},
|
||||
mixins: {
|
||||
validate: assertNodeType("InterfaceExtends"),
|
||||
optional: true,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@ -177,6 +181,51 @@ defineType("ClassDeclaration", {
|
||||
inherits: "ClassExpression",
|
||||
aliases: ["Scopable", "Class", "Statement", "Declaration"],
|
||||
fields: {
|
||||
id: {
|
||||
validate: assertNodeType("Identifier"),
|
||||
},
|
||||
typeParameters: {
|
||||
validate: assertNodeType(
|
||||
"TypeParameterDeclaration",
|
||||
"TSTypeParameterDeclaration",
|
||||
"Noop",
|
||||
),
|
||||
optional: true,
|
||||
},
|
||||
body: {
|
||||
validate: assertNodeType("ClassBody"),
|
||||
},
|
||||
superClass: {
|
||||
optional: true,
|
||||
validate: assertNodeType("Expression"),
|
||||
},
|
||||
superTypeParameters: {
|
||||
validate: assertNodeType(
|
||||
"TypeParameterInstantiation",
|
||||
"TSTypeParameterInstantiation",
|
||||
),
|
||||
optional: true,
|
||||
},
|
||||
implements: {
|
||||
validate: chain(
|
||||
assertValueType("array"),
|
||||
assertEach(
|
||||
assertNodeType("TSExpressionWithTypeArguments", "ClassImplements"),
|
||||
),
|
||||
),
|
||||
optional: true,
|
||||
},
|
||||
decorators: {
|
||||
validate: chain(
|
||||
assertValueType("array"),
|
||||
assertEach(assertNodeType("Decorator")),
|
||||
),
|
||||
optional: true,
|
||||
},
|
||||
mixins: {
|
||||
validate: assertNodeType("InterfaceExtends"),
|
||||
optional: true,
|
||||
},
|
||||
declare: {
|
||||
validate: assertValueType("boolean"),
|
||||
optional: true,
|
||||
@ -247,18 +296,21 @@ defineType("ExportNamedDeclaration", {
|
||||
optional: true,
|
||||
validate: chain(
|
||||
assertNodeType("Declaration"),
|
||||
function (node, key, val) {
|
||||
if (!process.env.BABEL_TYPES_8_BREAKING) return;
|
||||
Object.assign(
|
||||
function (node, key, val) {
|
||||
if (!process.env.BABEL_TYPES_8_BREAKING) return;
|
||||
|
||||
// This validator isn't put at the top level because we can run it
|
||||
// even if this node doesn't have a parent.
|
||||
// This validator isn't put at the top level because we can run it
|
||||
// even if this node doesn't have a parent.
|
||||
|
||||
if (val && node.specifiers.length) {
|
||||
throw new TypeError(
|
||||
"Only declaration or specifiers is allowed on ExportNamedDeclaration",
|
||||
);
|
||||
}
|
||||
},
|
||||
if (val && node.specifiers.length) {
|
||||
throw new TypeError(
|
||||
"Only declaration or specifiers is allowed on ExportNamedDeclaration",
|
||||
);
|
||||
}
|
||||
},
|
||||
{ oneOfNodeTypes: ["Declaration"] },
|
||||
),
|
||||
function (node, key, val) {
|
||||
if (!process.env.BABEL_TYPES_8_BREAKING) return;
|
||||
|
||||
@ -433,25 +485,31 @@ defineType("MetaProperty", {
|
||||
aliases: ["Expression"],
|
||||
fields: {
|
||||
meta: {
|
||||
validate: chain(assertNodeType("Identifier"), function (node, key, val) {
|
||||
if (!process.env.BABEL_TYPES_8_BREAKING) return;
|
||||
validate: chain(
|
||||
assertNodeType("Identifier"),
|
||||
Object.assign(
|
||||
function (node, key, val) {
|
||||
if (!process.env.BABEL_TYPES_8_BREAKING) return;
|
||||
|
||||
let property;
|
||||
switch (val.name) {
|
||||
case "function":
|
||||
property = "sent";
|
||||
break;
|
||||
case "new":
|
||||
property = "target";
|
||||
break;
|
||||
case "import":
|
||||
property = "meta";
|
||||
break;
|
||||
}
|
||||
if (!is("Identifier", node.property, { name: property })) {
|
||||
throw new TypeError("Unrecognised MetaProperty");
|
||||
}
|
||||
}),
|
||||
let property;
|
||||
switch (val.name) {
|
||||
case "function":
|
||||
property = "sent";
|
||||
break;
|
||||
case "new":
|
||||
property = "target";
|
||||
break;
|
||||
case "import":
|
||||
property = "meta";
|
||||
break;
|
||||
}
|
||||
if (!is("Identifier", node.property, { name: property })) {
|
||||
throw new TypeError("Unrecognised MetaProperty");
|
||||
}
|
||||
},
|
||||
{ oneOfNodeTypes: ["Identifier"] },
|
||||
),
|
||||
),
|
||||
},
|
||||
property: {
|
||||
validate: assertNodeType("Identifier"),
|
||||
@ -665,15 +723,21 @@ defineType("YieldExpression", {
|
||||
aliases: ["Expression", "Terminatorless"],
|
||||
fields: {
|
||||
delegate: {
|
||||
validate: chain(assertValueType("boolean"), function (node, key, val) {
|
||||
if (!process.env.BABEL_TYPES_8_BREAKING) return;
|
||||
validate: chain(
|
||||
assertValueType("boolean"),
|
||||
Object.assign(
|
||||
function (node, key, val) {
|
||||
if (!process.env.BABEL_TYPES_8_BREAKING) return;
|
||||
|
||||
if (val && !node.argument) {
|
||||
throw new TypeError(
|
||||
"Property delegate of YieldExpression cannot be true if there is no argument",
|
||||
);
|
||||
}
|
||||
}),
|
||||
if (val && !node.argument) {
|
||||
throw new TypeError(
|
||||
"Property delegate of YieldExpression cannot be true if there is no argument",
|
||||
);
|
||||
}
|
||||
},
|
||||
{ type: "boolean" },
|
||||
),
|
||||
),
|
||||
default: false,
|
||||
},
|
||||
argument: {
|
||||
|
||||
@ -11,6 +11,7 @@ import {
|
||||
classMethodOrPropertyCommon,
|
||||
classMethodOrDeclareMethodCommon,
|
||||
} from "./es2015";
|
||||
import { functionTypeAnnotationCommon } from "./core";
|
||||
|
||||
defineType("ArgumentPlaceholder", {});
|
||||
|
||||
@ -29,7 +30,18 @@ defineType("BindExpression", {
|
||||
visitor: ["object", "callee"],
|
||||
aliases: ["Expression"],
|
||||
fields: !process.env.BABEL_TYPES_8_BREAKING
|
||||
? {}
|
||||
? {
|
||||
object: {
|
||||
validate: Object.assign(() => {}, {
|
||||
oneOfNodeTypes: ["Expression"],
|
||||
}),
|
||||
},
|
||||
callee: {
|
||||
validate: Object.assign(() => {}, {
|
||||
oneOfNodeTypes: ["Expression"],
|
||||
}),
|
||||
},
|
||||
}
|
||||
: {
|
||||
object: {
|
||||
validate: assertNodeType("Expression"),
|
||||
@ -96,10 +108,13 @@ defineType("OptionalMemberExpression", {
|
||||
const normal = assertNodeType("Identifier");
|
||||
const computed = assertNodeType("Expression");
|
||||
|
||||
return function (node, key, val) {
|
||||
const validator = function (node, key, val) {
|
||||
const validator = node.computed ? computed : normal;
|
||||
validator(node, key, val);
|
||||
};
|
||||
// todo(ts): can be discriminated union by `computed` property
|
||||
validator.oneOfNodeTypes = ["Expression", "Identifier"];
|
||||
return validator;
|
||||
})(),
|
||||
},
|
||||
computed: {
|
||||
@ -211,6 +226,7 @@ defineType("ClassPrivateMethod", {
|
||||
],
|
||||
fields: {
|
||||
...classMethodOrDeclareMethodCommon,
|
||||
...functionTypeAnnotationCommon,
|
||||
key: {
|
||||
validate: assertNodeType("PrivateName"),
|
||||
},
|
||||
@ -226,6 +242,14 @@ defineType("Import", {
|
||||
|
||||
defineType("ImportAttribute", {
|
||||
visitor: ["key", "value"],
|
||||
fields: {
|
||||
key: {
|
||||
validate: assertNodeType("Identifier"),
|
||||
},
|
||||
value: {
|
||||
validate: assertNodeType("StringLiteral"),
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
defineType("Decorator", {
|
||||
|
||||
@ -65,6 +65,10 @@ defineType("JSXElement", {
|
||||
),
|
||||
),
|
||||
},
|
||||
selfClosing: {
|
||||
validate: assertValueType("boolean"),
|
||||
optional: true,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user