TypeScript:跨多个类型的接口?

TypeScript:跨多个类型的接口?,typescript,types,interface,casting,Typescript,Types,Interface,Casting,因此,我从一个端点获取数据,该端点返回一个具有相同接口的不同类型的集合…类似于: interface CommonInterface { public type: string; public commonProperty1: integer; public commonProperty2: boolean; } class Thing1 implements CommonInterface {} class Thing2 implements CommonInter

因此,我从一个端点获取数据,该端点返回一个具有相同接口的不同类型的集合…类似于:

interface CommonInterface {
    public type: string;
    public commonProperty1: integer;
    public commonProperty2: boolean;
}

class Thing1 implements CommonInterface {}

class Thing2 implements CommonInterface {}
因此,端点返回
CommonInterface[]
,它是
Thing1
Thing2
实例的混合体。
CommonInterface
上的属性之一是一个
类型
鉴别器,用于识别它是哪个“东西”

如何在TypeScript中对这种键入结构进行排序?我如何告诉TS数组的类型是
CommonInterface
,然后告诉它第一项(基于
type
值)是
Thing1
,其中第二项是
Thing2
,第三项是
Thing1


我做了一些搜索,但没有找到任何真正有意义的情况。提前感谢您的帮助

假设您得到了以下类定义:

class Thing1 implements CommonInterface {
    readonly type = "Thing1";
    commonProperty1 = 1;
    commonProperty2 = true;
    thing1Prop = "okay";
}

class Thing2 implements CommonInterface {
    readonly type = "Thing2";
    commonProperty1 = 2;
    commonProperty2 = false;
    thing2Prop = "okay";
}
我倾向于构建表示测试的
CommonInterface
Thing1
还是
Thing2
或其他东西。可能是这样的:

type Things = Thing1 | Thing2;
function isThing<T extends Things["type"]>(
    obj: CommonInterface, type: T
): obj is Extract<Things, { type: T }> {
    return obj.type === type;
}
function processCommonInterfaceArray(objs: CommonInterface[]) {
    objs.forEach(c => {
        if (isThing(c, "Thing1")) {
            c.thing1Prop.toUpperCase();
        } else if (isThing(c, "Thing2")) {
            c.thing2Prop.toUpperCase();
        } else {
            // c is some other commonInterface
            c.commonProperty1.toFixed();
        }
    })
}
从中可以看出,编译器正在使用
isThing(c,“Thing1”)
返回
true
,从而得出结论
c
必须是
Thing1
,因此具有
thing1Prop
。这同样适用于
isThing(c,“Thing2”)
Thing2
。因为你不能确定所有的
CommonInterface
对象都是
Thing1
Thing2
(没有什么能阻止某人拥有一个实现
CommonInterface
Thing3
),那么你需要对最后一个
else
子句做些什么


请注意,通常我希望您使用类似于
Things
的类型,而完全忘记
CommonInterface
。如果您可以重构键入,使端点返回
Things[]
而不是
CommonInterface[]
,那么您就不需要用户定义的类型保护来进行控制流缩小:

function processThings(objs: Things[]) {
    objs.forEach(c => {
        if (c.type === "Thing1") {
            c.thing1Prop.toUpperCase();
        } else {
            c.thing2Prop.toUpperCase();
        }
    })
}

好吧,希望这会有帮助;祝你好运


请考虑提供一个允许人们展示你的问题的方法。TypeScript中的接口不支持
public
修饰符
integer
不是已知类型,上面的类没有实现接口。@jcalz是的,我提供的代码不是typescript,而是后端类/接口的伪代码。我应该更明确地说明这一点。