-
Notifications
You must be signed in to change notification settings - Fork 12.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Enum Equality #1748
Comments
These enums are declared separately and are thus distinct in the type system. We don't use structural typing to determine enum compatibility. |
👍 |
@billti @RyanCavanaugh I stumbled over this today as well and found it annoying. What is the reasons behind that this is by design. |
👍 I think enums and classes should follow the same or as much as possible similar rules? module A {
export class C {
bar: string;
}
export enum E {
Prop = 0
}
}
module B {
export class C {
bar: string
}
export enum E {
Prop = 0
}
}
var c1:A.C;
var c2:B.C;
c2 = c1; // <-- no type error here
var e1:A.E;
var e2:B.E;
e2 = e1; // <-- type error here |
Enums are compared in a nominal fashion. similarly classes with private or protected members. so in the example above, if you add a private member the behavior will be identical to enums. The rational was that enums represent disjoint subtypes of number, and that trying to assign one value from one enum to another (even if the enums were identical in structure) is probably an error that the user want to know about. e.g.: const enum Direction {
up = 0,
down = 1
}
const enum Colors {
red = 0,
blue = 1
}
var color: Colors = Direction.up; // valid if structurally compared, as both have the same value, but probably an error. Having said that We have discussed this topic in the last design meeting, and i think we will be doping the nominal comparison for enums eventually. |
I am not sure I understand the definition you propose for structurally comparing enums where module A {
export class C {
bar = "hello";
}
}
module B {
export class C {
foo = "hello";
}
}
var a:A.C;
var b:B.C;
a=b; // <-- I correctly get an error here 👍 Also please consider the following case (which I think @dbaeumer actually hit): All node modules are authored in TypeScript and provide .d.ts files in npm such that the .d.ts file is discoverable with TypeScript's node module lookup rules. // node module a
export enum Type { File = 0, Folder = 1 } // node module b has a dependency on a
import {Type} from 'a';
export function compute(/*...*/): Type; // node module c depends on both a and b
import {Type} from 'a';
import {compute} from 'b';
var foo = compute(/*...*/);
// cannot really use foo in a typed manner The problem is that the fs has the following structure:
so TypeScript sees two different |
this sounds like #4800. Are the modules the same? are they flattened? can they be flattened? |
@mhegazy I actually hit this in another context (not with node modules) where I really just want enum structural typing. See https://github.com/Microsoft/vscode/blob/master/src/vs/workbench/api/browser/pluginHost.api.impl.ts#L112 and the many The problem is the following:
|
As per the design meeting notes #5943, enums should compare in a semi-nominal manner. where the enum names have to match, and the target has members with the same names as the source. |
I expected the two
CompilerOptions
to be type compatible.The text was updated successfully, but these errors were encountered: