Skip to content

transform-spread + typescript builds Flow annotation instead of TypeScript #9530

@azz

Description

@azz

Bug Report

Current Behavior

TypeError: Property types[0] of UnionTypeAnnotation expected node to be of a type ["FlowType"] but instead got "TSTypeAnnotation"
    at validate (/work/node_modules/@babel/types/lib/definitions/utils.js:128:13)
    at validator (/work/node_modules/@babel/types/lib/definitions/utils.js:97:7)
    at Object.validate (/work/node_modules/@babel/types/lib/definitions/utils.js:172:7)
    at validate (/work/node_modules/@babel/types/lib/validators/validate.js:17:9)
    at builder (/work/node_modules/@babel/types/lib/builders/builder.js:46:27)
    at UnionTypeAnnotation (/work/node_modules/@babel/types/lib/builders/generated/index.js:733:31)
    at Object.createUnionTypeAnnotation (/work/node_modules/@babel/types/lib/builders/flow/createUnionTypeAnnotation.js:20:47)
    at NodePath.ConditionalExpression (/work/node_modules/@babel/traverse/lib/path/inference/inferers.js:124:14)
    at NodePath._getTypeAnnotation (/work/node_modules/@babel/traverse/lib/path/inference/index.js:63:20)
    at NodePath.getTypeAnnotation (/work/node_modules/@babel/traverse/lib/path/inference/index.js:29:19)

Input Code

https://github.com/azz/babel-typescript-union-bug

function bug() {
  const x = 1 ? a() : b();

  return [...x];
}

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

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

Expected behavior/code

Not like this

Babel Configuration (.babelrc, package.json, cli command)

{
  "plugins": ["@babel/plugin-transform-spread"],
  "presets": ["@babel/preset-typescript"]
}

Environment

  • Babel version(s): 7.3.3
  • Node/npm version: 6.5.0
  • OS: macOS 10.14.2
  • Monorepo: no
  • How you are using Babel: cli

Possible Solution

The builder code for plugin-transform-spread is expecting a UnionTypeAnnotation instead of a TSUnionType in order to determine the type of x above, specifically in scope.toArray:

if (t.isIdentifier(node)) {
const binding = this.getBinding(node.name);
if (binding && binding.constant && binding.path.isGenericType("Array")) {
return node;
}
}

isGenericType ends up calling createUnionTypeAnnotation:

export function ConditionalExpression() {
return t.createUnionTypeAnnotation([
this.get("consequent").getTypeAnnotation(),
this.get("alternate").getTypeAnnotation(),
]);
}

Which creates a UnionTypeAnnotation, which works for Flow, but not TypeScript.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions