diff --git a/README.md b/README.md index 84f8ef4..1086af0 100644 --- a/README.md +++ b/README.md @@ -138,6 +138,8 @@ type res5 = Pipe< - [x] `ReturnType` - [x] `Parameters` - [x] `Parameter` + - [x] `MapReturnType` + - [x] `MapParameters` - [ ] Tuples - [x] `Create -> [X]` - [x] `Partition` diff --git a/src/internals/functions/Functions.ts b/src/internals/functions/Functions.ts index dc8a5b2..b0bc6fe 100644 --- a/src/internals/functions/Functions.ts +++ b/src/internals/functions/Functions.ts @@ -1,4 +1,4 @@ -import { Fn, PartialApply, unset, _ } from "../core/Core"; +import { Fn, PartialApply, unset, _, Call } from "../core/Core"; export namespace Functions { type ParametersImpl = fn extends (...args: infer args) => any @@ -67,4 +67,62 @@ export namespace Functions { export interface ReturnTypeFn extends Fn { return: ReturnTypeImpl; } + + /** + * Transforms the return type of a function type. + * + * @param fn - Type-level function to call on the return type. + * @param fnValue - The function type to update. + * @returns a function type with an updated return type. + * + * @example + * ```ts + * type T0 = Call< + * Functions.MapReturnType, + * (a: number, b: string) => 1 | 2 + * >; + * // => (a: number, b: string) => "1" | "2" + * ``` + */ + export type MapReturnType< + fn extends Fn | unset | _ = unset, + fnValue extends ((...args: any[]) => any) | _ | unset = unset + > = PartialApply; + + export interface MapReturnTypeFn extends Fn { + return: this["args"] extends [infer fn extends Fn, infer fnValue] + ? fnValue extends (...args: infer args) => infer returnType + ? (...args: args) => Call + : never + : never; + } + + /** + * Transforms the paramaters of a function type. + * + * @param fn - Type-level function to call on parameters. + * @param fnValue - The function type to update. + * @returns a function type with updated parameters. + * + * @example + * ```ts + * type T0 = Call< + F.MapParameters>, + (a: "1" | "2", b: "3" | "4") => void + >; + * // => (a: 1 | 2, b: 3 | 4) => void + * ``` + */ + export type MapParameters< + fn extends Fn | unset | _ = unset, + fnValue extends ((...args: any[]) => any) | _ | unset = unset + > = PartialApply; + + export interface MapParametersFn extends Fn { + return: this["args"] extends [infer fn extends Fn, infer fnValue] + ? fnValue extends (...args: infer args) => infer returnType + ? (...args: Extract, readonly any[]>) => returnType + : never + : never; + } } diff --git a/test/functions.test.ts b/test/functions.test.ts index 4a8edf2..793ec0f 100644 --- a/test/functions.test.ts +++ b/test/functions.test.ts @@ -1,4 +1,4 @@ -import { F, _ } from "../src/index"; +import { F, Numbers, Strings, Tuples, _ } from "../src/index"; import { Call } from "../src/internals/core/Core"; import { Equal, Expect } from "../src/internals/helpers"; @@ -23,4 +23,20 @@ describe("Functions", () => { // ^? type tes1 = Expect>; }); + it("MapReturnType", () => { + type res1 = Call< + // ^? + F.MapReturnType, + (a: string, b: number) => "1" | "2" + >; + type tes1 = Expect 1 | 2>>; + }); + it("MapParameters", () => { + type res1 = Call< + // ^? + F.MapParameters>, + (a: "1" | "2", b: "3" | "4") => void + >; + type tes1 = Expect void>>; + }); });