4

In my angular 6 file I've got an interface defined and then in a method that takes a generic parameter, T, I want to determine if T implements that interface at runtime. Is that possible?

I tried to do if (T instanceof INetworkObject) but the compiler doesn't like that.

export interface INetworkObject {
    fixNetworkObject(): void;
}

protected getTypedItem<T>(endpoint: string, C: { new(): T }): Observable<T> {
    return this.http.get<T>(`${this.baseUrl}/${endpoint}`)
        .pipe(map(element => {
            if (!element) {
                return null;
            }

            const ret = Object.assign(new C(), element);

            if (T.type instanceof NetworkObject) {

            }

            // This ugliness is what I'm doing now
            if (typeof ret['fixNetworkObject'] === 'function') {
                ret['fixNetworkObject']();
            }

Basically what I'm trying to do is call fixNetworkObject on ret if it implements that interface.

1
  • @IngoBürk I'm familiar with most of those, but the fact that it's a generic is what's causing me issues. T won't always implement NetworkObject. Commented Jul 19, 2018 at 5:46

1 Answer 1

5

Unfortunately, you can't use instanceof because interfaces don't exist at runtime. You need to declare a type guard like so (see the Advanced Types Documentation):

function isINetworkObject(obj: any): obj is INetworkObject {
  return typeof obj.fixNetworkObject === 'function';
}

Then modify your if:

if (isINetworkObkect(ret)) {
  ret.fixNetworkObject();
}
Sign up to request clarification or add additional context in comments.

5 Comments

That assumes that T always extends Lengthwise. I don't know that here. Sometimes it will, sometimes it won't.
I don't think so, because Fish there is the interface, right? I don't always have something of that type. That's why I need it as a runtime check.
So I see how that determines if it is that class or not. But how does ret there, which is a generic type, know that it can call fixNetworkObject(). Seems like that should be a typescript build error!
That is how the type guard works. The special is return type means that the function below will check for type safety however the user deems safe. If the function returns true then the argument specified is the type in question. Then if you have an if that depends on these is types it applies the type safety of the variable to the code block of the if (or else if you did an inverse or something).
It is also smart enough to handle returns, so you can do something like this: if (!isINetworkObkect(ret)) return; and all of the code in the function below would use the type.

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.