是否可以在 TypeScript 的类中定义类型(字符串文字联合)?

问题描述 投票:0回答:2

在 TypeScript 1.8 中,他们添加了一种称为“字符串文字类型”的新类型,它允许您声明只能是一组有限值中的一个的类型。他们给出的例子是:

type Easing = "ease-in" | "ease-out" | "ease-in-out";

但是,在他们的所有示例中,类型要么是在其所使用的类的外部定义的,要么是在没有别名的情况下内联定义的。正如在这个问题的答案中所解释的(相当简洁),类型别名声明的范围仅限于其包含的模块。

在我的项目中,我想为与特定类配对并在多个位置使用的字符串文字定义类型别名。由于我使用的 API 的结构,存在多个类,每个类都具有名称相同但潜在值不同的属性。如果可以的话,我希望保持代码整洁,并且不要有一堆带前缀的全局类型声明(

MyClassAPropertyValue
MyClassBPropertyValue
等)。

那么,有没有什么方法可以在类范围内声明

type
(最好是可以从外部模块使用它)?如果没有,是否有一个相近的替代品或计划的功能可以填充这个用例?


使用案例:

假设我有两个类来包装我的底层 API 数据。每个类代表不同的数据,它们只是碰巧有一些同名的属性。我想要一种定义属性的方法,如下所示:

export class APIObjectA {
    // Valid values in APIObjectA
    public type Property1Value = "possible_value_A" | "possible_value_B";
    public type Property2Value = "possible_value_C" | "possible_value_D";

    // Here, "Property1Value" refers to the version in APIObjectA
    public get property1(): Property1Value {
        // Return value of property1 from underlying API data
    }

    public get property2(): Property2Value {
        // ...
    }
}

export class APIObjectB {
    // Valid values in APIObjectB
    public type Property1Value = "possible_value_E" | "possible_value_F";
    public type Property2Value = "possible_value_G" | "possible_value_H";

    // In this context, "Property1Value" refers to the version in APIObjectB
    public get property1(): Property1Value {
        // ...
    }

    public get property2(): Property2Value {
        // ...
    }
}

然后,理想情况下,我能够在使用代码中引用特定类型,以便我到处都有类型:

var myNewValue: APIObjectB.Property1Value = "possible_value_F";
types typescript typescript1.8
2个回答
23
投票

您不能直接在类中定义类型(无论是嵌套类、枚举还是字符串文字类型)。

但是,如这个答案所示,您可以通过在同名模块中定义嵌套类型来解决这个问题。

export class APIObjectA {
    // Here, "Property1Value" refers to the version in APIObjectA
    public get property1(): APIObjectA.Property1Value {
        // Return value of property1 from underlying API data
    }

    public get property2(): APIObjectA.Property2Value {
        // ...
    }
}

module APIObjectA {
    // Valid values in APIObjectA
    export type Property1Value = "possible_value_A" | "possible_value_B";
    export type Property2Value = "possible_value_C" | "possible_value_D";
}

export class APIObjectB {
    // In this context, "Property1Value" refers to the version in APIObjectB
    public get property1(): APIObjectB.Property1Value {
        // ...
    }

    public get property2(): APIObjectB.Property2Value {
        // ...
    }
}

module APIObjectB {
    // Valid values in APIObjectB
    export type Property1Value = "possible_value_E" | "possible_value_F";
    export type Property2Value = "possible_value_G" | "possible_value_H";
}

请注意,您需要使用属性的返回类型的完全限定名称。例如,您需要使用

APIObjectB.Property1Value
而不是仅
Property1Value


0
投票

不确定在发布时(2017 年)是否可能,但现在使用 Typescript 5.4 似乎是可能的

  export class APIObjectA {
    // Valid values in APIObjectA
    public Property1Value: "possible_value_A" | "possible_value_B";
    public Property2Value: "possible_value_C" | "possible_value_D";

    // Here, "Property1Value" refers to the version in APIObjectA
    public get property1(): APIObjectA['Property1Value'] {
        return 'possible_value_A';
    }

    public get property2(): APIObjectA['Property2Value'] {
        return 'possible_value_C';
        // ...
    }
}
var myNewValue: APIObjectA['Property1Value'] = "possible_value_A";
© www.soinside.com 2019 - 2024. All rights reserved.