从枚举类型获取枚举项类型

时间:2016-09-07 09:19:27

标签: typescript

鉴于以下enum

enum Style {
    Compact,
    Switch,
    Default
}

如何从Style类型中获取typeof Style类型?例如,我想将它与我的enum-cast函数一起使用,该函数接受枚举定义和数字作为其参数,并返回数字"作为项目"如果该数字由指定的枚举定义,则为指定的枚举:

function castToEnum<T>(_enum: T, value: number): T {
    if (_enum.hasOwnProperty(value.toString())) {
        return value as any; // 'value' is defined by '_enum'.
    } else {
        throw new TypeError(`enum does not define value '${value}'.`);
    }
}

这就是我希望它的工作方式:

var style1 = castToEnum(Style, 0); // Ok, style1 === Style.Compact
var style2 = castToEnum(Style, 1); // Ok, style2 === Style.Switch
var style3 = castToEnum(Style, 2); // Ok, style3 === Style.Default
var style4 = castToEnum(Style, 3); // TypeError

在此,我希望styleX属于Style类型。但是,由于T上的泛型类型参数castToEnum被检测为类型为typeof Style,因此styleX也属于该类型。

Demo on Playground

我怎么能做到这一点?我尝试使用typeof,但它不适用于泛型类型参数,因为它们已经是类型。

如何进行此类型转换,从枚举类型转换为枚举类型?

修改

对于非抽象类,可以从具有以下函数签名的类类型中获取实例类型:

function createInstance<T>(_class: new () => T): T {
    return new _class();
}

这将有效地采用类型typeof T的参数,并在具有无参数构造函数签名的类的情况下返回类型T的值。不幸的是,这种方法不适用于枚举。

1 个答案:

答案 0 :(得分:0)

您需要收到枚举any

function castToEnum<T>(_enum: any, ordinal: number): T {
    if (_enum.hasOwnProperty(ordinal)) {
        return _enum[ordinal];
    } else {
        throw new TypeError(`enum does not define value '${ ordinal }'.`);
    }
}

console.log(castToEnum(Style, 0)); // Compact
console.log(castToEnum(Style, 1)); // Switch
console.log(castToEnum(Style, 2)); // Default
console.log(castToEnum(Style, 3)); // TypeError

code in playground

修改

这应该按照您的要求运作:

function castToEnum(_enum: any, ordinal: number): number {
    if (_enum[ordinal]) {
        return ordinal;
    } else {
        throw new TypeError(`enum does not define value '${ ordinal }'.`);
    }
}

var style: Style = castToEnum(Style, 1);
console.log(style === Style.Switch);
console.log(castToEnum(Style, 3)); // TypeError

code in playground

该函数需要返回number,否则返回:

style === Style.Switch

将是假的。
它适用于类型安全。