Skip to content

Commit

Permalink
Merge pull request #497 from braxtonhall/match
Browse files Browse the repository at this point in the history
More ergonomic `match`
  • Loading branch information
supermacro authored Aug 12, 2024
2 parents ced9108 + 1f87908 commit 3960060
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 10 deletions.
5 changes: 5 additions & 0 deletions .changeset/tall-berries-guess.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"neverthrow": patch
---

enhance type inferrence of `match`
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -448,10 +448,10 @@ Match callbacks do not necessitate to return a `Result`, however you can return

```typescript
class Result<T, E> {
match<A>(
match<A, B = A>(
okCallback: (value: T) => A,
errorCallback: (error: E) => A
): A => { ... }
errorCallback: (error: E) => B
): A | B => { ... }
}
```

Expand Down Expand Up @@ -1067,10 +1067,10 @@ The difference with `Result.match` is that it always returns a `Promise` because

```typescript
class ResultAsync<T, E> {
match<A>(
match<A, B = A>(
okCallback: (value: T) => A,
errorCallback: (error: E) => A
): Promise<A> => { ... }
errorCallback: (error: E) => B
): Promise<A | B> => { ... }
}
```

Expand Down
2 changes: 1 addition & 1 deletion src/result-async.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ export class ResultAsync<T, E> implements PromiseLike<Result<T, E>> {
)
}

match<A>(ok: (t: T) => A, _err: (e: E) => A): Promise<A> {
match<A, B = A>(ok: (t: T) => A, _err: (e: E) => B): Promise<A | B> {
return this._promise.then((res) => res.match(ok, _err))
}

Expand Down
6 changes: 3 additions & 3 deletions src/result.ts
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ interface IResult<T, E> {
* @param ok
* @param err
*/
match<A>(ok: (t: T) => A, err: (e: E) => A): A
match<A, B = A>(ok: (t: T) => A, err: (e: E) => B): A | B

/**
* Emulates Rust's `?` operator in `safeTry`'s body. See also `safeTry`.
Expand Down Expand Up @@ -309,7 +309,7 @@ export class Ok<T, E> implements IResult<T, E> {
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
match<A>(ok: (t: T) => A, _err: (e: E) => A): A {
match<A, B = A>(ok: (t: T) => A, _err: (e: E) => B): A | B {
return ok(this.value)
}

Expand Down Expand Up @@ -380,7 +380,7 @@ export class Err<T, E> implements IResult<T, E> {
return v
}

match<A>(_ok: (t: T) => A, err: (e: E) => A): A {
match<A, B = A>(_ok: (t: T) => A, err: (e: E) => B): A | B {
return err(this.error)
}

Expand Down
48 changes: 48 additions & 0 deletions tests/typecheck-tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,54 @@ type CreateTuple<L, V = string> =
});
});

(function describe(_ = 'match') {
(function it(_ = 'the type of the arguments match the types of the result') {
type OKExpectation = number
type ErrExpectation = string

ok<number, string>(123)
.match(
(val: OKExpectation): void => void val,
(val: ErrExpectation): void => void val,
);
err<number, string>("123")
.match(
(val: OKExpectation): void => void val,
(val: ErrExpectation): void => void val,
);
});

(function it(_ = 'infers the resulting value from match callbacks (same type)') {
type Expectation = boolean

const okResult: Expectation = ok<number, string>(123)
.match(
(val) => !!val,
(val) => !!val,
);
const errResult: Expectation = err<number, string>('123')
.match(
(val) => !!val,
(val) => !!val,
);
});

(function it(_ = 'infers the resulting value from match callbacks (different type)') {
type Expectation = boolean | bigint

const okResult: Expectation = ok<string, number>('123')
.match(
(val) => !!val,
(val) => BigInt(val),
);
const errResult: Expectation = err<string, number>(123)
.match(
(val) => !!val,
(val) => BigInt(val),
);
});
});

(function describe(_ = 'asyncAndThen') {
(function it(_ = 'Combines two equal error types (native scalar types)') {
type Expectation = ResultAsync<unknown, string>
Expand Down

0 comments on commit 3960060

Please sign in to comment.