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

transform-spread: create TS types (not Flow) when using TS #11378

Merged
merged 11 commits into from Apr 15, 2020
10 changes: 9 additions & 1 deletion packages/babel-traverse/src/path/inference/inferers.js
Expand Up @@ -89,7 +89,15 @@ export function LogicalExpression() {
]);
}

export function ConditionalExpression() {
export function ConditionalExpression(node) {
console.log(node);
Beraliv marked this conversation as resolved.
Show resolved Hide resolved
if (t.isTSTypeAnnotation(node)) {
Beraliv marked this conversation as resolved.
Show resolved Hide resolved
return t.createTSUnionType([
this.get("consequent").getTypeAnnotation(),
this.get("alternate").getTypeAnnotation(),
]);
}

return t.createUnionTypeAnnotation([
this.get("consequent").getTypeAnnotation(),
this.get("alternate").getTypeAnnotation(),
Expand Down
13 changes: 13 additions & 0 deletions packages/babel-traverse/test/fixtures/type-reference/input.ts
@@ -0,0 +1,13 @@
function bug() {
Beraliv marked this conversation as resolved.
Show resolved Hide resolved
const x = 1 ? a() : b();

return [...x];
}

function a(): number[] {
return [];
}

function b(): number[] {
return [];
}
@@ -0,0 +1,4 @@
{
"plugins": ["transform-spread"],
"presets": ["typescript"]
}
16 changes: 16 additions & 0 deletions packages/babel-types/src/builders/typescript/createTSUnionType.js
@@ -0,0 +1,16 @@
import { TSUnionType } from "../generated";
import removeTypeDuplicates from "../../modifications/typescript/removeTypeDuplicates";
Copy link
Contributor Author

@Beraliv Beraliv Apr 4, 2020

Choose a reason for hiding this comment

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


/**
* Takes an array of `types` and flattens them, removing duplicates and
* returns a `UnionTypeAnnotation` node containg them.
*/
export default function createTSUnionType(types: Array<Object>): Object {
const flattened = removeTypeDuplicates(types);

if (flattened.length === 1) {
return flattened[0];
} else {
return TSUnionType(flattened);
Beraliv marked this conversation as resolved.
Show resolved Hide resolved
}
}
@@ -0,0 +1,74 @@
import {
isTSAnyKeyword,
isTSUnionType,
isTSTypeParameter,
} from "../../validators/generated";

/**
* Dedupe type annotations.
*/
export default function removeTypeDuplicates(
nodes: Array<Object>,
): Array<Object> {
const generics = {};
// FIXME: I don't understand the purpose of bases for Flow (if it has an analogue for TS)
// const bases = {};
Beraliv marked this conversation as resolved.
Show resolved Hide resolved

// store union type groups to circular references
const typeGroups = [];

const types = [];

for (let i = 0; i < nodes.length; i++) {
const node = nodes[i];
if (!node) continue;

// detect duplicates
if (types.indexOf(node) >= 0) {
continue;
}

if (isTSAnyKeyword(node)) {
return [node];
}

// FIXME: I don't understand the purpose of bases for Flow (if it has an analogue for TS)
// if (isFlowBaseAnnotation(node)) {
// bases[node.type] = node;
// continue;
// }

if (isTSUnionType(node)) {
if (typeGroups.indexOf(node.types) < 0) {
nodes = nodes.concat(node.types);
typeGroups.push(node.types);
}
continue;
}

if (isTSTypeParameter(node)) {
Beraliv marked this conversation as resolved.
Show resolved Hide resolved
const name = node.name;

if (!generics[name]) {
generics[name] = node;
}

continue;
}

types.push(node);
}

// FIXME: I don't understand the purpose of bases for Flow (if it has an analogue for TS)
// add back in bases
// for (const type of Object.keys(bases)) {
// types.push(bases[type]);
// }

// add back in generics
for (const name of Object.keys(generics)) {
types.push(generics[name]);
}

return types;
}