使用打字稿接口继承进行类型检查

type check with typescript interface inheritance

我有一个接口和两个扩展它的接口:

interface Layer {
    name: string;
    pretty_name: string;
}

interface SubLayer extends Layer{
    url: string;
}

interface AnotherLayer extends Layer{
    file: string;
}

然后我有一个服务我有处理任何Layer参数的函数,然后需要区分子接口并根据:

调用正确的函数
class LayerDataService {

    static getLayer(layer: Layer) {
        if (......) {
            return LayerDataService.getSubLayer(layer as SubLayer );
        }
        else if (......) {
            return LayerDataService.getAnotherLayer(layer as AnotherLayer);
        }
    }

    static getAnotherLayer (layer: AnotherLayer) {

    }
    static getSubLayer(layer: SubLayer) {

    }
}

所以在 ..... 我想区分实现 SubLayer 的层和实现 AnotherLayer 的层。

所以我知道我不能使用 instanceof,因为它们不是 类,它们是实现接口的对象。但是有没有一种方法不需要像我在类型保护中那样手动检查每个属性?

不确定我是否理解正确,但我认为你可以使用类型保护功能。

function (layer: unknown): layer is AnotherLayer {
   return !!layer.file;
}

SubLayer 执行相同的操作,然后您可以将其用作标准函数,但在括号内,您会将其强类型化为指定类型。

由于接口在编译时被擦除,因此没有关于它们的运行时信息,因此没有 instanceof。我能想到的唯一解决方案是反转依赖关系,所以它是决定它如何被调用的层...

class LayerDataService {
    static getLayer(layer: Layer) {
        layer.get(this);
    }
}

interface Layer {
    name: string;
    pretty_name: string;
    
    get(service: LayerDataService): void;
}

interface SubLayer extends Layer{
    url: string;
}

interface AnotherLayer extends Layer{
    file: string;
}

这样每个实现都负责调用 LayerDataService 上的相关函数,这无疑增加了开销。我不完全确定这是否适用于您的情况,但我认为值得一提。