2017-10-15 107 views
1

我试图扩展一个不同文件中的导入枚举,并使用该扩展枚举另一个不同的文件在另一个文件中扩展导入的枚举并使用它

一般情况下

base.enum.ts

export enum MyEnum { 
    a = "Foo" 
} 

extended.enum.ts

import { MyEnum } from './base.enum'; 

declare module './base.enum' { 
    export enum MyEnum { 
     b = "Bar" 
    } 
} 

使用在index.ts

import { MyEnum } from './base.enum'; 
import './extended.enum'; // side-effects import (no usage of export) 

console.log(MyEnum.a); // prints "Foo" as expected 
console.log(MyEnum.b); // prints undefined, instead of the expected "Bar" 

(I” m在TypeScript 2.4.2中这样做orts字符串值枚举)

我用thisthis作为参考的SO问题,并阅读以下TypeScript issue in GitHub,仍然无法找到解决我的问题。使用的


实施例其类似于矿在动物/碱/动物types.enum.ts

基地枚举AnimalTypes:在动物/碱/动物

export enum AnimalTypes { } 

Base接口动物。 TS:

import { AnimalTypes } from './animal-types'; 
export interface Animal { 
    type: AnimalTypes; 
} 

动物/碱/ index.ts:

export * from './animal-types.enum'; 
export * from './animal'; 

动物扩展枚举AnimalTypes /动物types.enum.ts:

import { AnimalTypes } from './base/'; 
declare module './base/animal-types.enum' { 
    export enum AnimalTypes { 
     Cat = "cat", 
     Dog = "dog"/*, 
     ...*/ 
    } 
} 

混凝土猫类动物/ cat.ts:动物

import { Animal, AnimalTypes } from './base/'; 
import './animal-types.enum'; 
export class Cat implements Animal { 
    public type: AnimalTypes = AnimalTypes.Cat; // Usage of AnimalTypes with extended value 
} 

混凝土类犬/狗.TS:

import { Animal, AnimalTypes } from './base/'; 
import './animal-types.enum'; 
export class Dog implements Animal { 
    public type: AnimalTypes = AnimalTypes.Dog; // Usage of AnimalTypes with extended value 
} 

动物/ index.ts:

export * from './cat'; 
export * from './dog'; 
//... 

最终用途的动物/动物-manager.ts:

import { Animal, AnimalTypes} from './base/'; 
import { Cat, Dog/*, ...*/ } from '.'; 
import './animal-types'; // side-effects import (no usage of export) 

export class AnimalsManager { 
    public animals: { [animal: string]: Animal } = {}; // Animal dictionary (I would use AnimalTypes as key type but that isn't supported yet as far as I know). 
    constructor() { 
     this.animals[AnimalTypes.Cat] = new Cat(); 
     this.animals[AnimalTypes.Dog] = new Dog(); 
    } 
    //... 
} 

当尝试使用AnimalManager的animals[AnimalTypes.Cat]我会得到的animals[AnimalTypes.Dog]值,因为这两个AnimalTypes.CatAnimalTypes.Dog返回undefined(这意味着animals[AnimalTypes.Cat]是通过设置animals[AnimalTypes.Dog]覆盖)。


那么,有没有目前是这样如上所述的打字稿扩大进口枚举或将我砍在我的方式来获得支持这种延伸的自定义枚举?谢谢。

回答

0

TypeScript允许仅扩展declare module中的类型信息,从这些声明中不会执行任何代码。实际上,declare module内部的代码通常是不允许的,例如将一个函数放在一个body中会给出An implementation cannot be declared in ambient contexts错误。

所以你声明为MyEnum枚举类型的其他成员,但该成员没有在任何地方初始化,所以它的值在运行时为undefined。为了解决这个问题,你可以自己初始化:

extended.enum.ts

import { MyEnum } from './base.enum'; 

declare module './base.enum' { 
    export enum MyEnum { 
     b = "Bar" 
    } 
} 

const myEnumValues = MyEnum as any; 
myEnumValues["b"] = "Bar"; 

你要投MyEnumany第一,因为直接初始化是不允许的:

MyEnum["b"] = "Bar"; 

做不编译有错误

error TS2540:Cannot assign to 'b' because it is a constant or a read-only property. 
+0

非常感谢,这工作!烦恼的是你必须在'declare module'之外再次设置值。 – StartingAppDev