Last active
February 5, 2020 09:38
-
-
Save Reshetnyak/f2f4fce92e061486a2b231fd57ba5c78 to your computer and use it in GitHub Desktop.
Type guard helpers
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @type T {Object} expected type of provided object | |
* @param obj {Object} object | |
* @param prop {string} key of an object which indicates expected type | |
* @returns {boolean} provided object is type T | |
* | |
* @example | |
* interface Base { | |
* name: string; | |
* age: number; | |
* } | |
* | |
* interface ChildA extends Base { | |
* occupation: string; | |
* } | |
* | |
* interface ChildB extends Base { | |
* id: number; | |
* } | |
* | |
* function noop(arg: ChildA | ChildB): void { | |
* if (is<ChildA>(arg, 'occupation')) { | |
* // arg is narrowed to ChildA | |
* arg.name; | |
* } else { | |
* // arg is narrowed to ChildB | |
* arg.age; | |
* } | |
* } | |
*/ | |
function is<T extends object>(obj: object, prop: string): obj is T { | |
// Original `hasOwnProperty` is used to avoid collisions | |
return Object.prototype.hasOwnProperty.call(obj, prop); | |
} | |
// TODO: add JSDocs | |
function is< | |
T extends K, | |
K extends object = object | |
>(obj: K, prop: keyof T): obj is T | |
function is< | |
T extends K, | |
K extends object = object | |
>(obj: K, comparator: (obj: K) => obj is T): obj is T | |
function is< | |
T extends K, | |
K extends object = object | |
>(obj: K, propOrComparator: keyof T | Function): obj is T { | |
if (typeof propOrComparator === 'string') { | |
return Object.prototype.hasOwnProperty.call(obj, propOrComparator); | |
} else if (typeof propOrComparator === 'function') { | |
return propOrComparator(obj) | |
} | |
throw new Error('Second argument should be either key of the object or comparator function'); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment