Skip to content

Commit

Permalink
improve-typing
Browse files Browse the repository at this point in the history
  • Loading branch information
uriva committed Jan 8, 2025
1 parent 68e4589 commit 18177dd
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 3 deletions.
9 changes: 8 additions & 1 deletion src/composeTyping.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,16 @@ type UnwrapPromiseFn<T extends Func> = true extends IsAsync<T> ? (
) => UnwrapPromise<ReturnType<T>>
: T;

type GenericGeneric<S> = <T extends S>(x: T) => T;

// deno-lint-ignore no-explicit-any
type IsGeneric<F extends Func, T = any> = F extends GenericGeneric<T> ? true
: false;

type SimpleCompose<F, G> = G extends (...args: infer GArgs) => infer GReturn
? F extends (x: UnwrapPromise<GReturn>) => infer FReturn
? (...args: GArgs) => UnwrapPromise<FReturn>
? [true, true] extends [IsGeneric<G>, IsGeneric<F>] ? G
: (...args: GArgs) => UnwrapPromise<FReturn> // todo: does not preserve generics in case of generic identity.
: never
: never;

Expand Down
15 changes: 13 additions & 2 deletions src/composition.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import { assertEquals } from "std-assert";
import { multiply } from "./math.ts";
import { not } from "./operator.ts";
import { wrapPromise } from "./promise.ts";
import type { AsyncFunction } from "./typing.ts";
import { sleep } from "./time.ts";
import type { AsyncFunction } from "./typing.ts";

Deno.test("pipe with async functions", async () => {
assertEquals(
Expand Down Expand Up @@ -105,10 +105,21 @@ const _generics6: number = pipe(
<T>(t: T) => t,
)(1);

const _generics7: <T extends number>(t: T) => T = pipe(
<T extends number>(t: T) => t,
<T extends number>(t: T) => t,
);

const _generics8: <T extends number>(t: T) => T = pipe(
// @ts-expect-error no overlap
<T extends number>(t: T) => t,
<T extends string>(t: T) => t,
);

// failing typing tests:

// Generics understands contextual extends
// const _5 = <Fn extends (x: string) => number>(f: Fn) => {
// const _generics9 = <Fn extends (x: string) => number>(f: Fn) => {
// // @ts-expect-error first function does not match second
// pipe((x: number) => x, f);
// };
Expand Down

0 comments on commit 18177dd

Please sign in to comment.