Skip to content

Commit

Permalink
feat(match): allow to customize predicate
Browse files Browse the repository at this point in the history
  • Loading branch information
ecyrbe committed Aug 1, 2023
1 parent c6183a1 commit 7286851
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 11 deletions.
2 changes: 1 addition & 1 deletion src/internals/match/Match.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import * as Impl from "./impl/match";
*/
export type Match<
valueOrWithClauses = unset,
withClauses extends Impl.With<any, any, boolean>[] | unset | _ = unset
withClauses extends Impl.With<any, any, Fn>[] | unset | _ = unset
> = PartialApply<
MatchFn,
withClauses extends unset
Expand Down
24 changes: 14 additions & 10 deletions src/internals/match/impl/match.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,6 @@ type ReplaceArgsWithConstraint<pattern> = pattern extends arg<
? { [key in keyof pattern]: ReplaceArgsWithConstraint<pattern[key]> }
: pattern;

type DoesMatch<value, pattern, exact extends boolean> = exact extends true ?
Equal<value, pattern> :
value extends ReplaceArgsWithConstraint<pattern> ? true : false;

type ExtractArgObject<value, pattern> = pattern extends arg<infer N, any>
? { [K in N]: value }
: pattern extends []
Expand Down Expand Up @@ -61,16 +57,24 @@ type ExtractArgs<value, pattern> = WithDefaultArgs<
[value]
>;

export type Match<value, patterns extends With<any, any, boolean>[]> = patterns extends [
With<infer pattern, infer handler, infer exact>,
...infer restPatterns extends With<any, any, boolean>[]
interface PatternMatchFn extends Fn {
return: this["arg0"] extends ReplaceArgsWithConstraint<this["arg1"]> ? true : false;
}

interface ExactMatchFn extends Fn {
return: Equal<this["arg0"], this["arg1"]>;
}

export type Match<value, patterns extends With<any, any, Fn>[]> = patterns extends [
With<infer pattern, infer handler, infer predicate>,
...infer restPatterns extends With<any, any, Fn>[]
]
? DoesMatch<value, pattern, exact> extends true
? Call<predicate, value, pattern> extends true
? handler extends Fn
? Call<PartialApply<Extract<handler, Fn>, ExtractArgs<value, pattern>>>
: handler
: Match<value, restPatterns>
: never;

export type With<pattern, handler, exact extends boolean = false> = { exact: exact; pattern: pattern; handler: handler };
export type WithExact<pattern, handler> = With<pattern, handler, true>;
export type With<pattern, handler, predicate extends Fn = PatternMatchFn> = { predicate: predicate; pattern: pattern; handler: handler };
export type WithExact<pattern, handler> = With<pattern, handler, ExactMatchFn>;

0 comments on commit 7286851

Please sign in to comment.