Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: preserves overloads for non-async functions #22

11 changes: 5 additions & 6 deletions src/common/als.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import type { Any } from "src/common/types";
import { AsyncLocalStorage } from "node:async_hooks";

export function als<T, IArgs extends any[]>(
storage: AsyncLocalStorage<T>,
init: (...args: IArgs) => T
) {
return function <FArgs extends IArgs, FReturn>(
fn: (...args: FArgs) => FReturn
) {
): <Fn extends Any.Function>(fn: Fn) => Fn {
return function (fn) {
function newFn(...args: Parameters<typeof fn>) {
// @ts-ignore TS2683
// @ts-expect-error TS2683
const result = storage.run(init(...args), fn.bind(this), ...args);
return result;
}
Expand All @@ -20,6 +19,6 @@ export function als<T, IArgs extends any[]>(
}
);

return newFn;
return newFn as never;
};
}
14 changes: 8 additions & 6 deletions src/common/memoize.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
export function memoize<H extends (...args: any[]) => any>(
import { Any } from "src/common/types";

export function memoize<H extends Any.Function>(
hash: H,
cache = Object.create(null)
) {
return <FArgs extends any[], FReturn>(fn: (...args: FArgs) => FReturn) => {
): <Fn extends Any.Function>(fn: Fn) => Fn {
return (fn) => {
function newFn(...args: Parameters<typeof fn>) {
// @ts-ignore TS2683
// @ts-expect-error TS2683
const key = hash.apply(this, args);
if (!(key in cache)) {
// @ts-ignore TS2683
// @ts-expect-error TS2683
cache[key] = fn.apply(this, args);
}
return cache[key] as ReturnType<typeof fn>;
Expand All @@ -20,6 +22,6 @@ export function memoize<H extends (...args: any[]) => any>(
}
);

return newFn;
return newFn as never;
};
}
12 changes: 6 additions & 6 deletions src/common/trace.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
export const trace = <FArgs extends any[], FReturn>(
fn: (...args: FArgs) => FReturn
) => {
function newFn(...args: Parameters<typeof fn>) {
import type { Any } from "src/common/types";

export const trace = <Fn extends Any.Function>(fn: Fn): Fn => {
function newFn(...args: Parameters<Fn>) {
const tag = `${fn.name}(${args}) | duration`;
console.time(tag);
// @ts-ignore TS2683
// @ts-expect-error TS2683
const result = fn.apply(this, args);
console.timeEnd(tag);
return result;
Expand All @@ -17,5 +17,5 @@ export const trace = <FArgs extends any[], FReturn>(
}
);

return newFn;
return newFn as never;
};
8 changes: 8 additions & 0 deletions src/common/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export type {
Any,
}

declare namespace Any {
type Function<I extends Array<unknown> = Array<any>, O = any> = { (...args: I): O }
type Array<T = unknown> = ReadonlyArray<T>
}
14 changes: 7 additions & 7 deletions src/wrapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,17 +45,17 @@ type Spreadable<T> = T extends any[] ? T : never;

type Replace<Source, A, B, Sentinel = never> = Source extends Sentinel
? Omit<Source, keyof Sentinel> extends infer T
? Replace<LeftIfNotEqual<T, {}>, A, B, Sentinel> extends infer U
? U | B
: never // Dummy ternary just so we can get an alias T
: never // Dummy ternary just so we can get an alias U
? Replace<LeftIfNotEqual<T, {}>, A, B, Sentinel> extends infer U
? U | B
: never // Dummy ternary just so we can get an alias T
: never // Dummy ternary just so we can get an alias U
: Source extends Promise<infer T>
? Promise<Replace<T, A, B, Sentinel>>
: Source extends [infer AItem, ...infer ARest]
? [
Replace<AItem, A, B, Sentinel>,
...Spreadable<Replace<ARest, A, B, Sentinel>>
]
Replace<AItem, A, B, Sentinel>,
...Spreadable<Replace<ARest, A, B, Sentinel>>
]
: Source extends Record<string | number | symbol, any>
? { [K in keyof Source]: Replace<Source[K], A, B, Sentinel> }
: Source extends A
Expand Down
5 changes: 5 additions & 0 deletions test/trace.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import test from "ava";
import { trace } from "../src";
import type { Any } from "src/common/types";


declare function myFn<Args extends Any.Array>(arg_0: Args): string | number
declare function myFn<T, U>(arg_0: T, arg_1: U): T | U

test("maintains reference to this", async (t) => {
const data = {
Expand Down