-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(isInstanceOf): Added a variadic isInstanceOf that allows you to …
…catch errors by class type (#7) * feat(caseError): caseError now works with predicates instead of classes * feat(isInstanceOf): added isInstanceOf variadic function * fix(isInstanceOf): simplified typings of 'isInstanceOf'
- Loading branch information
Showing
6 changed files
with
305 additions
and
6 deletions.
There are no files selected for viewing
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
import { isInstanceOf } from './is-instance-of'; | ||
|
||
describe('isInstanceOf', () => { | ||
class Foo { | ||
Foo = 'Foo'; | ||
} | ||
|
||
class Bar { | ||
Bar = 'Bar'; | ||
} | ||
|
||
class Baz { | ||
Baz = 'Baz'; | ||
} | ||
|
||
describe('instanceOf with only one constructor', () => { | ||
it('An isInstanceOf function returns false when the object is not instance of the constructor', () => { | ||
// GIVEN: an "isInstanceOf" function that checks agains `Foo` | ||
const isInstanceOfFoo = isInstanceOf(Foo); | ||
// ...and an object that is not instance of `Foo` | ||
const bar = new Bar(); | ||
|
||
// WHEN: calling that "instanceOf" function with that object | ||
const result = isInstanceOfFoo(bar); | ||
|
||
// THEN: the result is false | ||
expect(result).toBe(false); | ||
}); | ||
|
||
it('An isInstanceOf function returns true when the object is instance of the constructor', () => { | ||
// GIVEN: an "isInstanceOf" function that checks agains `Foo` | ||
const isInstanceOfFoo = isInstanceOf(Foo); | ||
// ...and an object that is instance of `Foo` | ||
const foo = new Foo(); | ||
|
||
// WHEN: calling that "instanceOf" function with that object | ||
const result = isInstanceOfFoo(foo); | ||
|
||
// THEN: the result is true | ||
expect(result).toBe(true); | ||
}); | ||
}); | ||
|
||
describe('instanceOf with multiple constructors', () => { | ||
it('An isInstanceOf function returns false when the object is not instance of any of the constructors', () => { | ||
// GIVEN: an "isInstanceOf" function that checks agains `Foo` and `Bar` | ||
const isInstanceOfFooOrBar = isInstanceOf(Foo, Bar); | ||
// ...and an object that is neither instance of `Foo` or `Bar` | ||
const baz = new Baz(); | ||
|
||
// WHEN: calling that "instanceOf" function with that object | ||
const result = isInstanceOfFooOrBar(baz); | ||
|
||
// THEN: the result is false | ||
expect(result).toBe(false); | ||
}); | ||
|
||
it('An isInstanceOf function returns true when the object is instance of one of the constructors', () => { | ||
// GIVEN: an "isInstanceOf" function that checks agains `Foo` | ||
const isInstanceOfFooOrBar = isInstanceOf(Foo, Bar); | ||
// ...and an object that is instance of `Foo` | ||
const foo = new Foo(); | ||
|
||
// WHEN: calling that "instanceOf" function with that object | ||
const result = isInstanceOfFooOrBar(foo); | ||
|
||
// THEN: the result is true | ||
expect(result).toBe(true); | ||
}); | ||
|
||
it('An isInstanceOf function returns true when the object is instance of the other constructor', () => { | ||
// GIVEN: an "isInstanceOf" function that checks agains `Foo` | ||
const isInstanceOfFooOrBar = isInstanceOf(Foo, Bar); | ||
// ...and an object that is instance of `Foo` | ||
const bar = new Bar(); | ||
|
||
// WHEN: calling that "instanceOf" function with that object | ||
const result = isInstanceOfFooOrBar(bar); | ||
|
||
// THEN: the result is true | ||
expect(result).toBe(true); | ||
}); | ||
}); | ||
}); |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
export type Constructor<T> = { new (...args: any[]): T } | ||
|
||
export function isInstanceOf <A, B, C, D, E, F, G, H, I, J> ( | ||
constructor1: Constructor<A>, | ||
constructor2: Constructor<B>, | ||
constructor3: Constructor<C>, | ||
constructor4: Constructor<D>, | ||
constructor5: Constructor<E>, | ||
constructor6: Constructor<F>, | ||
constructor7: Constructor<G>, | ||
constructor8: Constructor<H>, | ||
constructor9: Constructor<I>, | ||
constructor10: Constructor<J> | ||
): | ||
(instance: any) => instance is A | B | C | D | E | F | G | H | I | J | ||
; | ||
export function isInstanceOf <A, B, C, D, E, F, G, H, I> ( | ||
constructor1: Constructor<A>, | ||
constructor2: Constructor<B>, | ||
constructor3: Constructor<C>, | ||
constructor4: Constructor<D>, | ||
constructor5: Constructor<E>, | ||
constructor6: Constructor<F>, | ||
constructor7: Constructor<G>, | ||
constructor8: Constructor<H>, | ||
constructor9: Constructor<I> | ||
): | ||
(instance: any) => instance is A | B | C | D | E | F | G | H | I | ||
; | ||
export function isInstanceOf <A, B, C, D, E, F, G, H> ( | ||
constructor1: Constructor<A>, | ||
constructor2: Constructor<B>, | ||
constructor3: Constructor<C>, | ||
constructor4: Constructor<D>, | ||
constructor5: Constructor<E>, | ||
constructor6: Constructor<F>, | ||
constructor7: Constructor<G>, | ||
constructor8: Constructor<H> | ||
): | ||
(instance: any) => instance is A | B | C | D | E | F | G | H | ||
; | ||
export function isInstanceOf <A, B, C, D, E, F, G> ( | ||
constructor1: Constructor<A>, | ||
constructor2: Constructor<B>, | ||
constructor3: Constructor<C>, | ||
constructor4: Constructor<D>, | ||
constructor5: Constructor<E>, | ||
constructor6: Constructor<F>, | ||
constructor7: Constructor<G> | ||
): | ||
(instance: any) => instance is A | B | C | D | E | F | G | ||
; | ||
export function isInstanceOf <A, B, C, D, E, F> ( | ||
constructor1: Constructor<A>, | ||
constructor2: Constructor<B>, | ||
constructor3: Constructor<C>, | ||
constructor4: Constructor<D>, | ||
constructor5: Constructor<E>, | ||
constructor6: Constructor<F> | ||
): | ||
(instance: any) => instance is A | B | C | D | E | F | ||
; | ||
export function isInstanceOf <A, B, C, D, E> ( | ||
constructor1: Constructor<A>, | ||
constructor2: Constructor<B>, | ||
constructor3: Constructor<C>, | ||
constructor4: Constructor<D>, | ||
constructor5: Constructor<E> | ||
): | ||
(instance: any) => instance is A | B | C | D | E | ||
; | ||
export function isInstanceOf <A, B, C, D> ( | ||
constructor1: Constructor<A>, | ||
constructor2: Constructor<B>, | ||
constructor3: Constructor<C>, | ||
constructor4: Constructor<D> | ||
): | ||
(instance: any) => instance is A | B | C | D | ||
; | ||
export function isInstanceOf <A, B, C> ( | ||
constructor1: Constructor<A>, | ||
constructor2: Constructor<B>, | ||
constructor3: Constructor<C> | ||
): | ||
(instance: any) => instance is A | B | C | ||
; | ||
export function isInstanceOf <A, B> ( | ||
constructor1: Constructor<A>, | ||
constructor2: Constructor<B> | ||
): | ||
(instance: any) => instance is A | B | ||
; | ||
export function isInstanceOf <A> ( | ||
constructor1: Constructor<A> | ||
): | ||
(instance: any) => instance is A | ||
; | ||
export function isInstanceOf <A> (...constructors: Constructor<A>[]) { | ||
return (instance: any): instance is A => | ||
constructors.some(aConstructor => | ||
instance instanceof aConstructor | ||
); | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
export * from './case-error' | ||
export * from './to-promise' | ||
export * from './operators/share' | ||
export * from './case-error'; | ||
export * from './to-promise'; | ||
export * from './operators/share'; | ||
export * from './is-instance-of'; |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
import { Task } from '@ts-task/task'; | ||
import { caseError, isInstanceOf } from '@ts-task/utils'; | ||
|
||
// We will test typings when using `isInstanceOf` together with `caseError` | ||
|
||
// We got some classes | ||
class Foo { | ||
Foo = 'Foo'; | ||
} | ||
|
||
class Bar { | ||
Bar = 'Bar'; | ||
} | ||
|
||
class Baz { | ||
Baz = 'Baz'; | ||
} | ||
|
||
// And a task that is rejected with all those classes | ||
const task = Task | ||
.resolve(9) | ||
.chain(x => x > 0 ? Task.resolve(x) : Task.reject(new Foo())) | ||
.chain(x => x > 0 ? Task.resolve(x) : Task.reject(new Bar())) | ||
.chain(x => x > 0 ? Task.resolve(x) : Task.reject(new Baz())) | ||
; | ||
|
||
task; // $ExpectType Task<number, UncaughtError | Foo | Bar | Baz> | ||
|
||
// If we handle the Foo errors | ||
const fooHandled = task | ||
.catch(caseError( | ||
isInstanceOf(Foo), | ||
_ => Task.resolve(0) | ||
)) | ||
; | ||
|
||
// ...we get a Task that is NOT rejected with the Foo errors | ||
fooHandled; // $ExpectType Task<number, UncaughtError | Bar | Baz> | ||
|
||
// If we handle the Foo and the Bar errors | ||
const fooAndBarHandled = task | ||
.catch(caseError( | ||
isInstanceOf(Foo, Bar), | ||
_ => Task.resolve(0) | ||
)) | ||
; | ||
|
||
// ...we get a Task that is neither rejected with the Foo or the Bar errors | ||
fooAndBarHandled; // $ExpectType Task<number, UncaughtError | Baz> | ||
|
||
// If we transform that last Task's Baz error into Bar error | ||
const bazTransformedToBar = fooAndBarHandled | ||
.catch(caseError( | ||
isInstanceOf(Baz), | ||
_ => Task.reject(new Bar()) | ||
)) | ||
; | ||
|
||
// We get a Task whose error is Bar (or UncaughtError) | ||
bazTransformedToBar; // $ExpectType Task<number, UncaughtError | Bar> |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import { isInstanceOf } from '@ts-task/utils'; | ||
|
||
// In this file we will check "isInstanceOf" functions inference. | ||
|
||
class Foo { | ||
Foo = 'Foo'; | ||
} | ||
|
||
class Bar { | ||
Bar = 'Bar'; | ||
} | ||
|
||
const foo = new Foo(); | ||
const bar = new Bar(); | ||
|
||
const isInstanceOfFoo = isInstanceOf(Foo); | ||
const isInstanceOfFooOrBar = isInstanceOf(Foo, Bar); | ||
|
||
// isInstanceOfFoo inference on foo | ||
if (isInstanceOfFoo(foo)) { | ||
// foo is Foo (duh!) | ||
foo; // $ExpectType Foo | ||
} else { | ||
// foo should never be "not Foo" | ||
foo; // $ExpectType never | ||
} | ||
|
||
// isInstanceOfFoo inference on bar | ||
if (isInstanceOfFoo(bar)) { | ||
// Someway bar is not only Bar, but also Foo | ||
bar; // $ExpectType Bar & Foo | ||
} else { | ||
// bar is Bar (duh!) | ||
bar; // $ExpectType Bar | ||
} | ||
|
||
// isInstanceOfFooOrBar inference on foo | ||
if (isInstanceOfFooOrBar(foo)) { | ||
// foo is only Foo | ||
foo; // $ExpectType Foo | ||
} else { | ||
// foo should never be "not Foo" | ||
foo; // $ExpectType never | ||
} | ||
|
||
// isInstanceOfFooOrBar inference on bar | ||
if (isInstanceOfFooOrBar(bar)) { | ||
// boo is only Bar | ||
bar; // $ExpectType Bar | ||
} else { | ||
// bar should never be "not Bar" | ||
bar; // $ExpectType never | ||
} |