Skip to content

Commit

Permalink
feat(match): allow to pass a checker instead of a predicate
Browse files Browse the repository at this point in the history
  • Loading branch information
ecyrbe committed Aug 1, 2023
1 parent 82e8dc1 commit ac50c84
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/internals/match/Match.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,5 @@ export namespace Match {
export type With<pattern, handler> = Impl.With<pattern, handler, PatternMatchFn>;
export type WithExact<pattern, handler> = Impl.With<pattern, handler, ExactMatchFn>;
export type WithPredicate<predicate extends Fn, pattern, handler> = Impl.With<pattern, handler, predicate>;
export type WithChecker<checker extends Fn, handler> = Impl.With<never, handler, checker>;
}
90 changes: 90 additions & 0 deletions test/match.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
arg1,
ComposeLeft,
Constant,
Fn,
Pipe,
} from "../src/internals/core/Core";
import { Equal, Expect } from "../src/internals/helpers";
Expand Down Expand Up @@ -138,8 +139,97 @@ describe("Match", () => {
type res4 = MatchTest<{ msg: "hello" }>;
// ^?
type test4 = Expect<Equal<res4, "don't match strictly with the provided types">>;
});

it("should match with predicates", () => {

interface TestPredicate extends Fn {
return: this["arg0"] extends this["arg1"] ? true : false;
}

type MatchTest<T> = Call<
Match<
T,
[
Match.WithPredicate<TestPredicate, string, Constant<"string">>,
Match.WithPredicate<TestPredicate, number, Constant<"number">>,
Match.WithPredicate<TestPredicate, boolean, Constant<"boolean">>,
]
>
>;

type res1 = MatchTest<"hello">;
// ^?
type test1 = Expect<Equal<res1, "string">>;

type res2 = MatchTest<string>;
// ^?
type test2 = Expect<Equal<res2, "string">>;

type res3 = MatchTest<1>;
// ^?
type test3 = Expect<Equal<res3, "number">>;

type res4 = MatchTest<number>;
// ^?
type test4 = Expect<Equal<res4, "number">>;

type res5 = MatchTest<true>;
// ^?
type test5 = Expect<Equal<res5, "boolean">>;

type res6 = MatchTest<boolean>;
// ^?
type test6 = Expect<Equal<res6, "boolean">>;
});

it("should match with checker", () => {
interface TestStringChecker extends Fn {
return: this["arg0"] extends string ? true : false;
}

interface TestNumberChecker extends Fn {
return: this["arg0"] extends number ? true : false;
}

interface TestBooleanChecker extends Fn {
return: this["arg0"] extends boolean ? true : false;
}

type MatchTest<T> = Call<
Match<
T,
[
Match.WithChecker<TestStringChecker, Constant<"string">>,
Match.WithChecker<TestNumberChecker, Constant<"number">>,
Match.WithChecker<TestBooleanChecker, Constant<"boolean">>,
]
>
>;

type res1 = MatchTest<"hello">;
// ^?
type test1 = Expect<Equal<res1, "string">>;

type res2 = MatchTest<string>;
// ^?
type test2 = Expect<Equal<res2, "string">>;

type res3 = MatchTest<1>;
// ^?
type test3 = Expect<Equal<res3, "number">>;

type res4 = MatchTest<number>;
// ^?
type test4 = Expect<Equal<res4, "number">>;

type res5 = MatchTest<true>;
// ^?
type test5 = Expect<Equal<res5, "boolean">>;

type res6 = MatchTest<boolean>;
// ^?
type test6 = Expect<Equal<res6, "boolean">>;
});

it("Handlers can also be regular values", () => {
Expand Down

0 comments on commit ac50c84

Please sign in to comment.