From fe4072203a45dbb716e274c999bfdf4623df2bf3 Mon Sep 17 00:00:00 2001 From: Ken Snyder Date: Mon, 16 Sep 2024 14:59:55 -0700 Subject: [PATCH] feat: added NumericSort utility --- src/types/lists/NumericSort.ts | 64 +++++++++++++++++++++++++++++++++ tests/lists/NumericSort.test.ts | 55 ++++++++++++++++++++++++++++ 2 files changed, 119 insertions(+) create mode 100644 src/types/lists/NumericSort.ts create mode 100644 tests/lists/NumericSort.test.ts diff --git a/src/types/lists/NumericSort.ts b/src/types/lists/NumericSort.ts new file mode 100644 index 00000000..bd7a85fa --- /dev/null +++ b/src/types/lists/NumericSort.ts @@ -0,0 +1,64 @@ +import { AsNumericArray } from "./AsNumericArray" + +type Iterator = + iterator['length'] extends n + ? iterator + : Iterator + +type Drop1 = + xs extends [any, ...infer tail] ? tail : [] + +type LessThanOrEqual = + [a, b] extends [[], [any, ...any]] + ? true + : [a, b] extends [[any,...any], []] + ? false + : [a, b] extends [[], []] + ? true + : LessThanOrEqual, Drop1> + +type GreaterThan = + [a, b] extends [[], [any, ...any]] + ? false + : [a, b] extends [[any,...any], []] + ? true + : [a, b] extends [[], []] + ? false + : GreaterThan, Drop1> + + +type FilterLessThanOrEqual = + xs extends [infer head, ...infer tail] + ? LessThanOrEqual, Iterator> extends true + ? [...output, head, ...FilterLessThanOrEqual] + : [...output, ...FilterLessThanOrEqual] + : [] + +type FilterGreaterThan = + xs extends [infer head, ...infer tail] + ? GreaterThan, Iterator> extends true + ? [...output, head, ...FilterGreaterThan] + : [...output, ...FilterGreaterThan] + : [] + + + type _Sort< + TValues extends number[], + TReverse extends boolean = false + > = + TValues extends [infer head, ...infer tail] + ? TReverse extends true + ? [...NumericSort, TReverse>, head, ...NumericSort, TReverse>] + : [...NumericSort, TReverse>, head, ...NumericSort, TReverse>] + : [] + + +/** + * **NumericSort**`` + * + * Sorts the values in a tuple numerically + */ +export type NumericSort< + TValues extends any[], + TReverse extends boolean = false +> = _Sort,TReverse> diff --git a/tests/lists/NumericSort.test.ts b/tests/lists/NumericSort.test.ts new file mode 100644 index 00000000..1ae55d72 --- /dev/null +++ b/tests/lists/NumericSort.test.ts @@ -0,0 +1,55 @@ +import { Equal, Expect } from "@type-challenges/utils"; +import { NumericSort } from "src/types/index"; +import { describe, it } from "vitest"; + +// Note: while type tests clearly fail visible inspection, they pass from Vitest +// standpoint so always be sure to run `tsc --noEmit` over your test files to +// gain validation that no new type vulnerabilities have cropped up. + +describe("Sort", () => { + + it("happy path", () => { + type S1 = NumericSort<[2,3,4,1]>; + type S2 = NumericSort<[22,33,44,11,11]>; + type S3 = NumericSort<[1,2,3,4]>; + + type SR1 = NumericSort<[2,3,4,1], true>; + type SR2 = NumericSort<[22,33,44,11,11], true>; + type SR3 = NumericSort<[1,2,3,4], true>; + + + + // @ts-ignore + type cases = [ + Expect>, + Expect>, + Expect>, + + Expect>, + Expect>, + Expect>, + ]; + }); + + it("with string literals", () => { + type S1 = NumericSort<[`2`,`3`,`4`,1]>; + type S2 = NumericSort<[22,`33`,44,11,11]>; + type S3 = NumericSort<[1,2,3,`4`]>; + + type SR1 = NumericSort<[`2`,`3`,`4`,`1`], true>; + type SR2 = NumericSort<[22,33,44,`11`,11], true>; + type SR3 = NumericSort<[1,`2`,`3`,4], true>; + + // @ts-ignore + type cases = [ + Expect>, + Expect>, + Expect>, + + Expect>, + Expect>, + Expect>, + ]; + }); + +});