Reputation: 1664
I have been following declaration-merging for typescript and I copied their example for merging a enum with some functions, and all I did was add export
to the enum and now I get errors.
export enum MyEnum {
Point = 'Point',
MultiPoint = 'MultiPoint',
}
namespace MyEnum {
export function parse(val: string): Type {
return MyEnum[val as keyof typeof MyEnum];
}
}
[ts] Individual declarations in merged declaration 'MyEnum' must be all exported or all local. [2395]
so fair enough it wants all or nothing, so I export out the namespace too.
export namespace Type { ... }
I now get another error.
[ts]
Type 'MyEnum | ((val: string) => MyEnum)' is not assignable to type 'MyEnum'.
Type '(val: string) => MyEnum' is not assignable to type 'MyEnum'. [2322]
I am not really sure if I am understanding that error message correctly, but it looks like it is trying to say that the MyEnum type can be either be a value of MyEnum or function is obviously failing, and also not what I was trying to do.
I also tried to remove the export from function parse
but then it just becomes unavailable. I have tried adding 'static' in various places but nothing seems to work.
All I am trying to do currently is
const value: string = getString();
const pointType = MyEnum.parse(value);
But I do plan on having more advanced stuff in the future and would just like to understand what I am doing wrong?
Upvotes: 3
Views: 3883
Reputation: 250036
In adding an extra member to the enum (you are adding parse
method) you changed the what indexing into the enum
will produce and what the keys of enum
will be.
keyof typeof MyEnum
is going to be "Point" | "MultiPoint" | "parse"
, so it will include the extra member.
Also typeof MyEnum[keyof typeof MyEnum]
will be MyEnum | ((val: string) => MyEnum)
, including the new member signature.
You can check for parse (which you may want to handle explicitly) :
export enum MyEnum {
Point = 'Point',
MultiPoint = 'MultiPoint',
}
export namespace MyEnum {
export function parse(val: string): MyEnum {
const key = val as keyof typeof MyEnum
if (key === 'parse') throw new Error("parse !");
return MyEnum[key]
}
}
Or you can just use an assertion that excludes parse
:
export enum MyEnum {
Point = 'Point',
MultiPoint = 'MultiPoint',
}
export namespace MyEnum {
export function parse(val: string): MyEnum {
return MyEnum[val as Exclude<keyof typeof MyEnum, 'parse'>]
}
}
Upvotes: 6