0

I have an interface and two interfaces that extend it:

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

interface SubLayer extends Layer{
    url: string;
}

interface AnotherLayer extends Layer{
    file: string;
}

Then I a service I have function that handles any Layer argument, and then needs to distinguish between the sub-interfaces and call the correct functions according:

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) {

    }
}

So on the ..... there I want to distinguish between layers which implement SubLayer and layers implementing AnotherLayer.

So I know I can't use instanceof, because they aren't classes, they're objects implementing interfaces. But is there a way that doesn't involve manually checking each-and-every attribute manually like I can do in type guards?

2 Answers 2

1

Since interfaces are erased at compile time, there's no runtime information about them, hence no instanceof. The only solution I can think of is to invert the dependency, so it's the layer that decides how it's called...

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;
}

This way each implementation is responsible for calling the relevant function on the LayerDataService, which admittedly adds overhead. I'm not entirely sure whether this would work in your case, but I thought worth mentioning.

Sign up to request clarification or add additional context in comments.

1 Comment

Yeah that could work. I went another way and that is to convert my interfaces into classes instead. I'll post the answer to that
0

Not sure if I understand correctly, but you can possibly use type guard function I think.

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

Do the same for SubLayer, then you can use it as standard function but inside the parenthesis you will have it strongly typed as the specified type.

1 Comment

That would require me to check every property of the interface manually in the guard, which seems a bit redundant since I already defined the interface itself. If I change my interface, I also need to change it twice, once in the interface definition and once in the type guard. So basically duplicating the interface definition. I was hoping there is a better way. Similar to instanceof.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.