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

fix: type instantiation is excessively deep and possibly infinite in pipe #258

Merged
merged 1 commit into from
Mar 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions src/Lazy/pipeLazy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,6 @@ import type ReturnPipeType from "../types/ReturnPipeType";
* see {@link https://fxts.dev/docs/toAsync | toAsync},
* {@link https://fxts.dev/docs/map | map}, {@link https://fxts.dev/docs/filter | filter}
*/
// eslint-disable-next-line
// @ts-ignore
// prettier-ignore
function pipeLazy<T1, R>(
f1: (a: Awaited<T1>) => R
Expand Down
13 changes: 10 additions & 3 deletions src/types/ReturnPipeType.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type Awaited from "./Awaited";
import type { TuplifyUnion } from "./ExcludeObject";
import type Equals from "./Equals";
import type Head from "./Head";
import type Tail from "./Tail";

Expand All @@ -13,7 +13,7 @@ type HasPromise<T extends any[]> = Head<T> extends never

type PossiblyHasPromise<T extends any[]> = Head<T> extends never
? false
: HasPromise<TuplifyUnion<Head<T>>> extends true
: Equals<Head<T>, Head<T> | Promise<Awaited<Head<T>>>> extends 1
? true
: T["length"] extends 0
? false
Expand All @@ -27,7 +27,7 @@ type PipeLast<T extends any[]> = T["length"] extends 0
? never
: PipeLast<Tail<T>>;

type ReturnPipeType<
type _ReturnPipeType<
T extends any[],
R = Awaited<PipeLast<T>>,
> = HasPromise<T> extends true
Expand All @@ -36,4 +36,11 @@ type ReturnPipeType<
? Promise<R> | R
: R;

type ReturnPipeType<
T extends any[],
R = Awaited<PipeLast<T>>,
> = _ReturnPipeType<T, R> extends Promise<never>
? never
: _ReturnPipeType<T, R>;

export default ReturnPipeType;
73 changes: 73 additions & 0 deletions type-check/pipe.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,77 @@
() => 2,
);

const Code = {
None: "NONE",
_00: "00",
_11: "11",
_13: "13",
_15: "15",
_17: "17",
_19: "19",
_21: "21",
_23: "23",
_25: "25",
_27: "27",
_29: "29",
_32: "32",
_34: "34",
_41: "41",
_43: "43",
_46: "46",
_52: "52",
_54: "54",
_56: "56",
_58: "58",
_62: "62",
_64: "64",
_66: "66",
_68: "68",
_72: "72",
_81: "81",
_83: "83",
_85: "85",
_96: "96",
_10: "10",
_12: "12",
_14: "14",
_16: "16",
_18: "18",
_20: "20",
_22: "22",
_24: "24",
_26: "26",
_28: "28",
_31: "31",
_33: "33",
_36: "36",
_42: "42",
_44: "44",
_51: "51",
_53: "53",
_55: "55",
_57: "57",
_61: "61",
_63: "63",
_65: "65",
_67: "67",
_71: "71",
_73: "73",
_74: "74",
_75: "75",
_76: "76",
_82: "82",
_84: "84",
_95: "95",
} as const;

type Code = (typeof Code)[keyof typeof Code];
const res18 = pipe({ code: Code.None }, (_: { code: Code }): Code => Code.None);

Check warning on line 141 in type-check/pipe.test.ts

View workflow job for this annotation

GitHub Actions / build (18.x)

'_' is defined but never used
const res19 = pipe(
{ code: Code.None },
async (_: { code: Code }): Promise<Code> => Code.None,

Check warning on line 144 in type-check/pipe.test.ts

View workflow job for this annotation

GitHub Actions / build (18.x)

'_' is defined but never used
);

checks([
check<typeof res1, string, Test.Pass>(),
check<typeof res2, number, Test.Pass>(),
Expand All @@ -91,4 +162,6 @@
check<typeof res15, Promise<never>, Test.Pass>(),
check<typeof res16, never, Test.Pass>(),
check<typeof res17, Promise<never>, Test.Pass>(),
check<typeof res18, Code, Test.Pass>(),
check<typeof res19, Promise<Code>, Test.Pass>(),
]);
Loading