class-validator icon indicating copy to clipboard operation
class-validator copied to clipboard

feature: improve isInstance type definition

Open 9oelM opened this issue 2 years ago • 1 comments

Description

isInstance type definition could be improved. Currently the type definition is as follows:

export declare function isInstance(object: unknown, targetTypeConstructor: new (...args: any[]) => any): boolean;

However this does not tell Typescript that object is indeed a type of new (...args: any[]) => any. So whenever you want to do something like:

class A {
   @IsInt()
   a: number
}

class B {
   @IsInt()
   b: number
}

// deliberately loosely typed (imagine, this could be an input from users)
const random: A | B = new A();

if (isInstance(random, A)) {
   // wanna do something about 'a', but random's type is still A | B here
   // error
   const { a } = random
}

Proposed solution

It should be simple if we just use a type predicate:

    function isInstanceImproved<ClassConstructor extends new (...args: any[]) => any>(
      object: unknown,
      targetTypeConstructor: ClassConstructor,
    ): object is InstanceType<ClassConstructor> {
      return isInstance(object, targetTypeConstructor);
    }

and use it like

if (isInstanceImproved(random, A)) {
   // now it works
   const { a } = random
}

In fact I'm using this in my code already.

9oelM avatar Sep 07 '23 05:09 9oelM

Also it seems that there're no test cases covering isInstance and IsInstance?

9oelM avatar Sep 07 '23 05:09 9oelM