-
Notifications
You must be signed in to change notification settings - Fork 70
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add non-spread overload for Result.all #86
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,11 +22,11 @@ | |
"@types/jest": "^26.0.22", | ||
"conditional-type-checks": "^1.0.5", | ||
"copyfiles": "^2.4.1", | ||
"jest": "^26.6.3", | ||
"jest": "^29.7.0", | ||
"prettier": "^2.2.1", | ||
"rxjs": "^6.6.7", | ||
"ts-jest": "^26.5.4", | ||
"tslib": "^2.1.0", | ||
"typescript": "^4.2" | ||
"ts-jest": "^29.1.2", | ||
"tslib": "^2.6.2", | ||
"typescript": "^5.4" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Bumping to typescript 5.X allows the use of const type params. |
||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -30,7 +30,7 @@ interface BaseResult<T, E> extends Iterable<T extends Iterable<infer U> ? U : ne | |
* @param msg the message to throw if Ok value. | ||
*/ | ||
expectErr(msg: string): T; | ||
|
||
/** | ||
* Returns the contained `Ok` value. | ||
* Because this function may throw, its use is generally discouraged. | ||
|
@@ -296,9 +296,19 @@ export namespace Result { | |
* Parse a set of `Result`s, returning an array of all `Ok` values. | ||
* Short circuits with the first `Err` found, if any | ||
*/ | ||
export function all<const T extends Result<any, any>[]>(results: T): Result<ResultOkTypes<T>, ResultErrTypes<T>[number]> | ||
export function all<T extends Result<any, any>[]>( | ||
...results: T | ||
): Result<ResultOkTypes<T>, ResultErrTypes<T>[number]> | ||
export function all<T extends Result<any, any>[]>( | ||
arg0: Head<T> | T, ...argN: Tail<T> | ||
): Result<ResultOkTypes<T>, ResultErrTypes<T>[number]> { | ||
const results = arg0 === undefined | ||
? [] | ||
: Array.isArray(arg0) | ||
? arg0 as T | ||
: [arg0, ...argN] as T; | ||
|
||
const okResult = []; | ||
for (let result of results) { | ||
if (result.ok) { | ||
|
@@ -315,9 +325,19 @@ export namespace Result { | |
* Parse a set of `Result`s, short-circuits when an input value is `Ok`. | ||
* If no `Ok` is found, returns an `Err` containing the collected error values | ||
*/ | ||
export function any<const T extends Result<any, any>[]>(results: T): Result<ResultOkTypes<T>[number], ResultErrTypes<T>> | ||
export function any<T extends Result<any, any>[]>( | ||
...results: T | ||
): Result<ResultOkTypes<T>[number], ResultErrTypes<T>> | ||
export function any<T extends Result<any, any>[]>( | ||
arg0: Head<T> | T, ...argN: Tail<T> | ||
): Result<ResultOkTypes<T>[number], ResultErrTypes<T>> { | ||
const results = arg0 === undefined | ||
? [] | ||
: Array.isArray(arg0) | ||
? arg0 as T | ||
: [arg0, ...argN] as T; | ||
|
||
const errResult = []; | ||
|
||
// short-circuits | ||
|
@@ -363,3 +383,8 @@ export namespace Result { | |
return val instanceof Err || val instanceof Ok; | ||
} | ||
} | ||
|
||
// Utility types | ||
type Head<T extends any[]> = T extends [any, ...infer R] ? | ||
T extends [...infer F, ...R] ? F : never : never | ||
type Tail<T extends any[]> = T extends [any, ...infer R] ? R : never | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These could likely be removed since the arrays I'm parsing above are typed as any[]. I could just as easily type the arguments as arg0: T[0] | T, argN: ...T but using these types are technically truer to what's going on. |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -110,20 +110,39 @@ test('Result.all', () => { | |
expect(all0).toMatchResult(Ok([])); | ||
eq<typeof all0, Result<[], never>>(true); | ||
|
||
const all0_array = Result.all([]); | ||
expect(all0_array).toMatchResult(Ok([])); | ||
eq<typeof all0_array, Result<[], never>>(true); | ||
|
||
const all1 = Result.all(ok0, ok1); | ||
expect(all1).toMatchResult(Ok([3, true])); | ||
eq<typeof all1, Result<[number, boolean], never>>(true); | ||
|
||
const all3 = Result.all(err0, err1); | ||
expect(all3).toMatchResult(Err(err0.val)); | ||
eq<typeof all3, Result<[never, never], symbol | Error>>(true); | ||
const all1Array = Result.all([ok0, ok1]); | ||
expect(all1Array).toMatchResult(Ok([3, true])); | ||
eq<typeof all1Array, Result<[number, boolean], never>>(true); | ||
|
||
const all2 = Result.all(err0, err1); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Corrected the naming indexes being off for all2 and onward |
||
expect(all2).toMatchResult(Err(err0.val)); | ||
eq<typeof all2, Result<[never, never], symbol | Error>>(true); | ||
|
||
const all2Array = Result.all([err0, err1]); | ||
expect(all2Array).toMatchResult(Err(err0.val)); | ||
eq<typeof all2Array, Result<[never, never], symbol | Error>>(true); | ||
|
||
const all3 = Result.all(...([] as Result<string, number>[])); | ||
eq<typeof all3, Result<string[], number>>(true); | ||
|
||
const all3Array = Result.all([] as Result<string, number>[]); | ||
eq<typeof all3Array, Result<string[], number>>(true); | ||
|
||
const all4 = Result.all(...([] as Result<string, number>[])); | ||
eq<typeof all4, Result<string[], number>>(true); | ||
const all4 = Result.all(ok0, ok1, ok2, err2); | ||
expect(all4).toMatchResult(Err(9)); | ||
eq<typeof all4, Result<[number, boolean, 8, boolean], boolean | 9>>(true); | ||
|
||
const all5 = Result.all(ok0, ok1, ok2, err2); | ||
expect(all5).toMatchResult(Err(9)); | ||
eq<typeof all5, Result<[number, boolean, 8, boolean], boolean | 9>>(true); | ||
const all4Array = Result.all([ok0, ok1, ok2, err2]); | ||
expect(all4Array).toMatchResult(Err(9)); | ||
eq<typeof all4Array, Result<[number, boolean, 8, boolean], boolean | 9>>(true); | ||
}); | ||
|
||
test('Result.any', () => { | ||
|
@@ -138,20 +157,39 @@ test('Result.any', () => { | |
expect(any0).toMatchResult(Err([])); | ||
eq<typeof any0, Result<never, []>>(true); | ||
|
||
const any0Array = Result.any(); | ||
expect(any0Array).toMatchResult(Err([])); | ||
eq<typeof any0Array, Result<never, []>>(true); | ||
|
||
const any1 = Result.any(ok0, ok1); | ||
expect(any1).toMatchResult(Ok(3)); | ||
eq<typeof any1, Result<number | boolean, [never, never]>>(true); | ||
|
||
const any3 = Result.any(err0, err1); | ||
expect(any3).toMatchResult(Err([err0.val, err1.val])); | ||
eq<typeof any3, Result<never, [symbol, Error]>>(true); | ||
const any1Array = Result.any([ok0, ok1]); | ||
expect(any1Array).toMatchResult(Ok(3)); | ||
eq<typeof any1Array, Result<number | boolean, [never, never]>>(true); | ||
|
||
const any2 = Result.any(err0, err1); | ||
expect(any2).toMatchResult(Err([err0.val, err1.val])); | ||
eq<typeof any2, Result<never, [symbol, Error]>>(true); | ||
|
||
const any2Array = Result.any([err0, err1]); | ||
expect(any2Array).toMatchResult(Err([err0.val, err1.val])); | ||
eq<typeof any2Array, Result<never, [symbol, Error]>>(true); | ||
|
||
const any3 = Result.any(...([] as Result<string, number>[])); | ||
eq<typeof any3, Result<string, number[]>>(true); | ||
|
||
const any3Array = Result.any([] as Result<string, number>[]); | ||
eq<typeof any3Array, Result<string, number[]>>(true); | ||
|
||
const any4 = Result.any(...([] as Result<string, number>[])); | ||
eq<typeof any4, Result<string, number[]>>(true); | ||
const any4 = Result.any(err0, err1, err2, ok2); | ||
expect(any4).toMatchResult(Ok(8)); | ||
eq<typeof any4, Result<boolean | 8, [symbol, Error, 9, boolean]>>(true); | ||
|
||
const any5 = Result.any(err0, err1, err2, ok2); | ||
expect(any5).toMatchResult(Ok(8)); | ||
eq<typeof any5, Result<boolean | 8, [symbol, Error, 9, boolean]>>(true); | ||
const any4Array = Result.any([err0, err1, err2, ok2]); | ||
expect(any4Array).toMatchResult(Ok(8)); | ||
eq<typeof any4Array, Result<boolean | 8, [symbol, Error, 9, boolean]>>(true); | ||
}); | ||
|
||
test('Result.wrap', () => { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This silences the warnings that global ts-jest configuration is deprecated