Skip to content

Commit

Permalink
fix(babel-types): accept UnaryExpression in TSLiteralType (#13525)
Browse files Browse the repository at this point in the history
* fix(babel-types): add validator for TSLiteralType to accept UnaryExpression

seems that the generated files is missing typings

fix #13327

* fix(babel-types): add allowlist for TSLiteralType

now generated types seems correct

* fix(babel-types): use oneOfNodeTypes instead of oneOf
  • Loading branch information
colinaaa committed Jul 2, 2021
1 parent 4ee78eb commit fce35af
Show file tree
Hide file tree
Showing 5 changed files with 129 additions and 8 deletions.
7 changes: 6 additions & 1 deletion packages/babel-types/src/ast-types/generated/index.ts
Expand Up @@ -1905,7 +1905,12 @@ export interface TSMappedType extends BaseNode {

export interface TSLiteralType extends BaseNode {
type: "TSLiteralType";
literal: NumericLiteral | StringLiteral | BooleanLiteral | BigIntLiteral;
literal:
| NumericLiteral
| StringLiteral
| BooleanLiteral
| BigIntLiteral
| UnaryExpression;
}

export interface TSExpressionWithTypeArguments extends BaseNode {
Expand Down
3 changes: 2 additions & 1 deletion packages/babel-types/src/builders/generated/index.ts
Expand Up @@ -1328,7 +1328,8 @@ export function tsLiteralType(
| t.NumericLiteral
| t.StringLiteral
| t.BooleanLiteral
| t.BigIntLiteral,
| t.BigIntLiteral
| t.UnaryExpression,
): t.TSLiteralType {
return builder("TSLiteralType", ...arguments);
}
Expand Down
44 changes: 38 additions & 6 deletions packages/babel-types/src/definitions/typescript.ts
Expand Up @@ -15,6 +15,7 @@ import {
functionDeclarationCommon,
classMethodOrDeclareMethodCommon,
} from "./core";
import is from "../validators/is";

const bool = assertValueType("boolean");

Expand Down Expand Up @@ -335,12 +336,43 @@ defineType("TSLiteralType", {
aliases: ["TSType", "TSBaseType"],
visitor: ["literal"],
fields: {
literal: validateType([
"NumericLiteral",
"StringLiteral",
"BooleanLiteral",
"BigIntLiteral",
]),
literal: {
validate: (function () {
const unaryExpression = assertNodeType(
"NumericLiteral",
"BigIntLiteral",
);
const unaryOperator = assertOneOf("-");

const literal = assertNodeType(
"NumericLiteral",
"StringLiteral",
"BooleanLiteral",
"BigIntLiteral",
);
function validator(parent, key: string, node) {
// type A = -1 | 1;
if (is("UnaryExpression", node)) {
// check operator first
unaryOperator(node, "operator", node.operator);
unaryExpression(node, "argument", node.argument);
} else {
// type A = 'foo' | 'bar' | false | 1;
literal(parent, key, node);
}
}

validator.oneOfNodeTypes = [
"NumericLiteral",
"StringLiteral",
"BooleanLiteral",
"BigIntLiteral",
"UnaryExpression",
];

return validator;
})(),
},
},
});

Expand Down
@@ -0,0 +1,31 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`builders typescript tsLiteralType accept unary expression 1`] = `
Object {
"literal": Object {
"argument": Object {
"type": "NumericLiteral",
"value": 1,
},
"operator": "-",
"prefix": true,
"type": "UnaryExpression",
},
"type": "TSLiteralType",
}
`;

exports[`builders typescript tsLiteralType accept unary expression 2`] = `
Object {
"literal": Object {
"argument": Object {
"type": "BigIntLiteral",
"value": "123456789",
},
"operator": "-",
"prefix": true,
"type": "UnaryExpression",
},
"type": "TSLiteralType",
}
`;
52 changes: 52 additions & 0 deletions packages/babel-types/test/builders/typescript/tsLiteralType.js
@@ -0,0 +1,52 @@
import * as t from "../../..";

describe("builders", function () {
describe("typescript", function () {
describe("tsLiteralType", function () {
it("accept unary expression", function () {
expect(
t.tsLiteralType(t.unaryExpression("-", t.numericLiteral(1))),
).toMatchSnapshot();
expect(
t.tsLiteralType(t.unaryExpression("-", t.bigIntLiteral("123456789"))),
).toMatchSnapshot();
});
it("throws with non-numeric argument", function () {
expect(() => {
t.tsLiteralType(t.unaryExpression("-", t.stringLiteral(1)));
}).toThrow("Property value expected type of string but got number");
expect(() => {
t.tsLiteralType(t.unaryExpression("-", t.objectExpression([])));
}).toThrow(
'Property argument of UnaryExpression expected node to be of a type ["NumericLiteral","BigIntLiteral"] but instead got "ObjectExpression"',
);
});
});
it("throws with bad operator", function () {
expect(() => {
t.tsLiteralType(t.unaryExpression("+", t.numericLiteral(1)));
}).toThrow(
'Property operator expected value to be one of ["-"] but got "+"',
);

// should check operator first since it appears first
expect(() => {
t.tsLiteralType(t.unaryExpression("+", t.objectExpression([])));
}).toThrow(
'Property operator expected value to be one of ["-"] but got "+"',
);

expect(() => {
t.tsLiteralType(t.unaryExpression("~", t.numericLiteral(1)));
}).toThrow(
'Property operator expected value to be one of ["-"] but got "~"',
);

expect(() => {
t.tsLiteralType(t.unaryExpression("void", t.numericLiteral(1)));
}).toThrow(
'Property operator expected value to be one of ["-"] but got "void"',
);
});
});
});

0 comments on commit fce35af

Please sign in to comment.