Skip to content

Import named default is typed differently than default import (with moduleResolution: node16) #49567

@calebeby

Description

@calebeby

Bug Report

🔎 Search Terms

default import, default export, named default export, module resolution, node 16

🕗 Version & Regression Information

Version 4.7.3

I also tried nightly, it is present there too.

  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about default imports/exports
  • I was unable to test this on prior versions because they didn't have the node16 setting

⏯ Playground Link

Can't use playground because it requires multiple files.

https://github.com/calebeby/ts-import-bug

💻 Code

In node, mod2 and def are the "CJS namespace import" as described in the Node docs.

import mod2, {default as def} from 'foo'

// TS thinks this is false; it is actually true
console.log(def === mod2)

// TS thinks this works but it doesn't (at runtime def === mod2)
def()

foo.d.ts:

export declare function def(): void
export default def

If I switch moduleResolution to node, mod2 and def have the same type (not matching node's native ESM behavior, but that is expected since moduleResolution is not set to node16)

🙁 Actual behavior

a.mts:11:13 - error TS2367: This condition will always return 'false' since the types '() => void' and 'typeof import("/Users/calebeby/Projects/ts-import-bug/foo/foo")' have no overlap.

🙂 Expected behavior

def and mod2 should have the same type (the CJS namespace). TS should say that the def() line is an error. def === mod2 should not say This condition will always return 'false'

Metadata

Metadata

Assignees

Labels

BugA bug in TypeScript

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions