Skip to content

esModuleInterop conflates default import type with that of a member named "default" #22812

@kourge

Description

@kourge

TypeScript Version: 2.8.0-dev.20180322

Search Terms:
esModuleInterop

Code

The flag --esModuleInterop must be enabled.

./index.ts

import Point from "./point";

const C = Point;
const p = new C(1, 2);

./point/index.js

function Point(x, y) {
  this.x = x;
  this.y = y;
}

Point.default = "foo";

module.exports = Point;

./point/index.d.ts

declare class Point {
  x: number;
  y: number;

  constructor(x: number, y: number);

  static default: "foo";
}

export = Point;

Expected behavior:

The code compiles.

Actual behavior:

index.ts(4,11): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature.

Playground Link:

This is not reproducible on Playground.

Additional Information:

The static member default causes TypeScript to mistake the type of the imported member Point as that of the static member, which is "foo" in this case, rather than the class Point, which is approximately the merger of interface Point { x: number; y: number} and var Point: { new(x: number, y: number): Point; default: "foo"; }.

This impacts using yargs with @types/yargs in the wild.

Metadata

Metadata

Assignees

Labels

BugA bug in TypeScriptDomain: ES ModulesThe issue relates to import/export style module behaviorFixedA PR has been merged for this issue

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions