Skip to content

Types are not imported properly for packages that use exports.default. #25854

Closed
@zavr-1

Description

@zavr-1

TypeScript Version: 3.1.0-dev

Search Terms: type export default

Code and Actual Behaviour

Scenario 1 (perfect): export default, import alias

tt.js

/**
 * Run this function
 * @param {string} t
 */
export default function testFunction(t) {
  return t
}

t.js

import t from './tt'

t
ScreenshotResult

test

The preview shows correctly.

Scenario 2 (Bug): exports.default, import originalName

tt.js (compiled w/ babel)

Object.defineProperty(exports, '__esModule', {
  value: true,
})
exports.default = testFunction

/**
 * Run this function
 * @param {string} t
 */
function testFunction(t) {
  return t
}

t.js

import testFunction from './tt'

testFunction(
ScreenshotsResult

test

test

There's no description on hover, but it comes up when starting to type arguments. But this is only because it's got the same name so VS Code looks up by the name. Proof: if function is not exported, it will still show description. Therefore, same as case 3.

Scenario 3 (Bug): exports.default, import alias

tt.js (compiled w/ babel)

Object.defineProperty(exports, '__esModule', {
  value: true,
})
exports.default = testFunction

/**
 * Run this function
 * @param {string} t
 */
function testFunction(t) {
  return t
}

t.js

import t from './tt'

t(
ScreenshotsResult

test

test

There's no description on hover, it does not come up when starting to type.

Expected behavior: Should always work as scenario 1.

So it basically means that all modules transpiled with babel must be imported using their original name? And even then it's only because it has got the same name.

Consider having 2 files:

tt.js

exports.default = testFunction

/**
 * Run this function (test 1)
 * @param {string} t1
 */
function testFunction(t1) {
  return t1
}

and

tt2.js

exports.default = testFunction

/**
 * Run this function (test 2)
 * @param {string} t2
 */
function testFunction(t2) {
  return t2
}

and a file in which I want to use them:

t.js

import testFunction from './tt'
import testFunction2 from './tt2'

/** @type {typeof import('./tt2')} */
testFunction2()

I won't be able to ever see type of testFunction2 even using typeof {import}? Unless I do module.exports = testFunction in tt2.js which Babel never does (and there's no setting for it). I think TypeScript should parse exports.default = in the same way as module.exports = as babel@5 did export then this way, whereas babel@6 doesn't.

https://github.com/59naga/babel-plugin-add-module-exports#readme

I can't even use the above plugin because even though it adds module.exports = exports.default; VS Code does not assign the type to module.exports.

Metadata

Metadata

Assignees

Labels

BugA bug in TypeScriptNeeds More InfoThe issue still hasn't been fully clarified

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions