Problem
Sometimes instanceof
might not be enough when working on a library that may potentially be installed multiple times in
a project. More on that on my blog.
Solution
As described on my blog - using special @type
property to indicate final type
of an object.
@pallad/type-check
is a tool that helps to achieve it in easy way.
Join our discord server
npm install @pallad/type-check
Usage with TypeCheck
instance in private scope.
import {TypeCheck} from '@pallad/type-check';
// Create TypeCheck instance with globally unique identifier for class
const CHECK = new TypeCheck<SomeLibraryClass>('some-library-class-unique-identifier')
export class SomeLibraryClass {
constructor() {
// assign necessary properties to current instance
CHECK.assign(this);
}
static isType = CHECK.isType
}
SomeLibraryClass.isType(new SomeLibraryClass()); // true
Usage with TypeCheck.clazz
.
import {TypeCheck} from '@pallad/type-check';
const CHECK = new TypeCheck<SomeLibraryClass>('some-library-class-unique-identifier')
export class SomeLibraryClass extends CHECK.clazz {
// properties assignment are done in constructor automatically
// static `isType` method is also assigned
}
SomeLibraryClass.isType(new SomeLibraryClass()); // true
Type identifiers (provided in TypeCheck's
constructor) must be globally unique so there is no potential conflict with
other type check from other libraries. Therefore recommended pattern fo identifier is: [packageName]/[className]
For example:
@pallad/type-check/SomeClassName
@pallad/secret/Secret
Obviously everything is properly typed and proper type guards are applied
const CHECK = new TypeCheck<Foo>('foo')
export class Foo extends CHECK.clazz {
prineMe() {
return 'hello';
}
}
if (Foo.isType(value)) {
// at this stage Typescript knows that `value` is a type of `Foo`
value.printMe();
}
Object can can hold multiple types for flexibility purposes.
const CHECK1 = new TypeCheck('foo')
const CHECK2 = new TypeCheck('bar')
const value = {};
CHECK1.assign(value);
CHECK2.assign(value);
CHECK1.isType(value); // true
CHECK2.isType(value); // true