vendettacbs
vendettacbs

Reputation: 189

How to create custom typeguard that checks whether a value is instance of a given class or not?

I am trying to implement a custom typeguard function which checks whether a given value is instance of given class or not.

I tried implementing the same in the following way:

function isObject<T>(value: any, className: T = Object as any): value is T {
        return (
            value &&
            typeof value === 'object' &&
            value instanceof (className as any)
        );
}

let myObj:Foo;
if(isObject(fooObj, Foo)) {
    myObj = fooObj;
}

But the above-given code throws an error: Type 'typeof Foo' is not assignable to type 'Foo'

Upvotes: 2

Views: 56

Answers (1)

Titian Cernicova-Dragomir
Titian Cernicova-Dragomir

Reputation: 249536

The problem is since you pass Foo as the second parameter T will end up representing the class not an instance of the class. You can extract the instance using the InstanceType conditional type:

class Foo { private x: null}
function isObject<T extends new (...a: any[])=> any>(value: any, className: T = Object as any): value is InstanceType<T> {
        return (
            value &&
            typeof value === 'object' &&
            value instanceof (className as any)
        );
}
let fooObj: unknown;
let myObj:Foo;
if(isObject(fooObj, Foo)) {
    myObj = fooObj;
}

Note istanceof will act as a type-guard itself.

Upvotes: 2

Related Questions