From 1bed975a10d9c1c3d430e51897a332a1be2f2c02 Mon Sep 17 00:00:00 2001 From: uri Date: Tue, 7 Jan 2025 03:40:33 +0200 Subject: [PATCH] improve-async-detection --- src/composition.test.ts | 15 +++++++++++++-- src/typing.ts | 10 ++++++++-- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/composition.test.ts b/src/composition.test.ts index 7ae3dff..81eb876 100644 --- a/src/composition.test.ts +++ b/src/composition.test.ts @@ -87,11 +87,22 @@ const _1 = number>(f: Fn) => { pipe((x: T) => x, f); }; +// Generics does not make everything async. +const _2: number = pipe((x: T) => x, (y: number) => y)(1); + +// Generics extends Promise is considered async. +const _3: number = await pipe( + (x: T) => Promise.resolve(x), + (y: number) => y, +)(1); + // failing typing tests: -// const _2 = pipe((x: T) => x, (y: number) => y)(1) + 7; +// Generics can infer by the last function +// const _4: number = pipe((y: number) => y, (x: T) => x)(1); -// const _3 = number>(f: Fn) => { +// Generics understands contextual extends +// const _5 = number>(f: Fn) => { // // @ts-expect-error first function does not match second // pipe((x: number) => x, f); // }; diff --git a/src/typing.ts b/src/typing.ts index b8f369e..4fd4cb4 100644 --- a/src/typing.ts +++ b/src/typing.ts @@ -4,9 +4,15 @@ export type Union = T[number]; // deno-lint-ignore no-explicit-any export type AsyncFunction = (...args: any[]) => Promise; -export type AnyAsync = Functions extends [infer f, ...infer rest] +export type AnyAsync = Functions extends [infer F, ...infer Rest] // deno-lint-ignore no-explicit-any - ? f extends AsyncFunction ? any : AnyAsync + ? F extends (...args: any[]) => infer R // Extract return type + // deno-lint-ignore no-explicit-any + ? R extends Promise // Check if it returns a Promise + // deno-lint-ignore no-explicit-any + ? any + : AnyAsync + : AnyAsync : never; export type Unary = (_: Input) => Output;