Skip to content

Enum export not working across multiple projects #4800

Description

The error relates to enums, and exports using the new typescript node resolution (with the typings property in the package.json). I have tested this on typescript@next.

The bug can be reproduced through the following scenario: (please go to https://github.com/christyharagan/typeScript-enum-export-bug to find this code):

Three projects: a, b, c.

b depends on a
c depends on b

a exports an enum through its index.ts:

export enum E{}

b then exports a function that returns E through its index.ts:

import {E} from 'a'
export function f():E {
  return null
}

c then consumes f through its index.ts:

import {E} from 'a'
import {f} from 'b'

let e:E = f()

There is now an error for e:

Type 'E' is not assignable to type 'E'.

All three packages have a package.json that looks like this:

{
  "name": "b",
  "version": "1",
  "main": "lib/index.js",
  "typings": "lib/index.d.ts",
  "dependencies": {
    "a": "1"
  }
}

And a tsconfig.json that looks like:

{
    "compilerOptions": {
        "declaration": true,
        "module": "commonjs",
        "rootDir": "./src",
        "target": "es5",
        "outDir": "./lib"
    },
    "files": [
        "src/index.ts"
    ]
}

Furthermore, this defect occurs if f were to export another symbol (e.g. an interface) which references an exported enum somewhere within it's structure or hierarchy.

This only seems to affect enums, not other types.

Activity

  1. mhegazy commented on Sep 15, 2015

    @mhegazy
    Contributor

    The problem is a/index.ts is loaded twice from two places, node_modules\a and node_modules\b\node_modules\a, and from the compiler perspective they are two different modules.

    Enums are not checked structurally, each any two enum types are not assignable to each other, regardless of their shape; other structural checks would work, e.g. passing an interface with he same shape as the expected target type. A class with a private member, however, will behave like an enum, as a private has to originate from the same declaration, and as mentioned above, they are not.

    Solutions, npm dedupe should solve this issue, assuming the version of the packages is compatible. the other possible solution would be implementing the suggestion in #4665 (comment).

    The typescript resolver should attempt to dedupe packages in similar setup, so marking it as a bug.

  2. mhegazy commented on Dec 1, 2015

    @mhegazy
    Contributor

    After discussion this some more, 1. npm v3 and later should flatten by default, so no additional work needed by the compiler, and 2. enums should not be compared nominally, see #5740

  3. added
    Won't FixThe severity and priority of this issue do not warrant the time or complexity needed to fix it
    on Dec 1, 2015
  4. xogeny commented on Dec 31, 2015

    @xogeny

    I don't understand, what is the resolution here? I am seeing the same issue. I simply want to define an enum in some dependency and then use it across projects. Your argument seems to be that an enum cannot be exported as a type (because possible values are not also exported?) and, therefore, two references to the same enum "type" via different paths are not considered equivalent types?

    I think I understand the semantic challenge here. But in practical terms, it seems like this makes an enum completely useless (at least in the context of reusable, modular code). If the enum cannot be exported then it can only be referenced internally within that module (i.e., it must be treated as effectively private to that module). Is my understanding correct? Is this really the final word on the enum type? If so, I'll need to switch all my enums to primitive types...which would be a real shame and a real loss for type safety. Or am I missing something?

  5. mhegazy commented on Jan 4, 2016

    @mhegazy
    Contributor

    Michael Tiller (@xogeny) this should be fixed in #6036

  6. xogeny commented on Jan 4, 2016

    @xogeny

    Great. Thanks. 👏

    I think I've already picked this up in typescript@next since I haven't seen this issue there.

  7. locked and limited conversation to collaborators on Jun 19, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugA bug in TypeScriptWon't FixThe severity and priority of this issue do not warrant the time or complexity needed to fix it

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions