Comparing version 1.0.8 to 1.0.9
@@ -32,2 +32,5 @@ import { Apply, Call, Fn } from "../../core/Core"; | ||
type RecursiveGet<Obj, pathList> = Obj extends any ? pathList extends [infer first, ...infer rest] ? first extends keyof Obj ? RecursiveGet<Obj[first], rest> : [first, Obj] extends [`${number}` | "number", any[]] ? RecursiveGet<Extract<Obj, any[]>[number], rest> : undefined : Obj : never; | ||
export type PartialDeep<T> = T extends object ? { | ||
[P in keyof T]?: PartialDeep<T[P]>; | ||
} : T; | ||
export type Update<obj, path, fnOrValue> = RecursiveUpdate<obj, ParsePath<path>, fnOrValue>; | ||
@@ -34,0 +37,0 @@ type RecursiveUpdate<obj, pathList, fnOrValue> = obj extends any ? pathList extends [infer first, ...infer rest] ? first extends keyof obj ? { |
@@ -134,2 +134,18 @@ import { IsArrayStrict, Prettify } from "../helpers"; | ||
/** | ||
* Makes all levels of an object optional | ||
* @description This function is used to make all levels of an object optional | ||
* @param obj - The object to make levels optional | ||
* @returns The object with its levels made optional | ||
* | ||
* @example | ||
* ```ts | ||
* type T0 = Call<Objects.PartialDeep, {a: 1; b: true }>; // { a?:1; b?: true} | ||
* type T1 = Call<Objects.PartialDeep, {a: 1; b: { c: true } }>; // { a?:1; b?: { c?: true } } | ||
* type T2 = Call<Objects.PartialDeep, {a: 1; b: { c: true, d: { e: false } } }>; // { a?:1; b?: { c?: true, d?: { e?: false } } } | ||
*/ | ||
export type PartialDeep<obj = unset> = PartialApply<PartialDeepFn, [obj]>; | ||
interface PartialDeepFn extends Fn { | ||
return: this["args"] extends [infer obj] ? Impl.PartialDeep<obj> : never; | ||
} | ||
/** | ||
* Updates an object or a tuple type. | ||
@@ -136,0 +152,0 @@ * @description This function takes an object, a path to one of its properties, |
@@ -14,2 +14,3 @@ export declare namespace Std { | ||
type _Partial<a> = Partial<a>; | ||
type _NonNullable<a> = NonNullable<a>; | ||
} |
@@ -57,2 +57,20 @@ import { Numbers as N, Numbers } from "../numbers/Numbers"; | ||
/** | ||
* `Unions.ToIntersection` turns a tuple into an intersection type. | ||
* @param tuple - any tuple. | ||
* @returns an intersection of all member of the tuple | ||
* @example | ||
* ```ts | ||
* type T0 = Call<Unions.ToIntersection, [{a: string}, {b: number}]>; // {a: string} & {b: number} | ||
* ``` | ||
*/ | ||
export type ToIntersection<tuple = unset> = PartialApply<ToIntersectionFn, [ | ||
tuple | ||
]>; | ||
interface ToIntersectionFn extends Fn { | ||
return: this["args"] extends [infer tuples extends readonly any[], ...any] ? Eval<Tuples.Reduce<IntersectFn, unknown, tuples>> : never; | ||
} | ||
interface IntersectFn extends Fn { | ||
return: this["arg0"] & this["arg1"]; | ||
} | ||
/** | ||
* Returns the first element of a tuple. | ||
@@ -414,2 +432,23 @@ * @params args[0] - A tuple. | ||
/** | ||
* Concatenate two tuples together | ||
* @param tuple1 - A list of types | ||
* @param tuple2 - Another list of types | ||
* @returns [...tuple1, ...tuple2] | ||
* @example | ||
* ```ts | ||
* type T0 = Call2<Tuples.Concat, [1], [2, 3]>; // [1, 2, 3] | ||
* ``` | ||
*/ | ||
export type Concat<tuple1 = unset, tuple2 = unset> = PartialApply<ConcatFn, [ | ||
tuple1, | ||
tuple2 | ||
]>; | ||
interface ConcatFn extends Fn { | ||
return: this["args"] extends [ | ||
infer t1 extends readonly any[], | ||
infer t2 extends readonly any[], | ||
...any | ||
] ? [...t1, ...t2] : never; | ||
} | ||
/** | ||
* Splits a tuple into two groups based on a predicate: | ||
@@ -461,3 +500,3 @@ * - The first group contains elements predicate returns true for. | ||
*/ | ||
export type Zip<arr0 extends unknown[] | _ | unset = unset, arr1 extends unknown[] | _ | unset = unset, arr2 extends unknown[] | _ | unset = unset, arr3 extends unknown[] | _ | unset = unset, arr4 extends unknown[] | _ | unset = unset, arr5 extends unknown[] | _ | unset = unset, arr6 extends unknown[] | _ | unset = unset, arr7 extends unknown[] | _ | unset = unset, arr8 extends unknown[] | _ | unset = unset, arr9 extends unknown[] | _ | unset = unset> = PartialApply<ZipWith<args>, [ | ||
export type Zip<arr0 extends unknown[] | _ | unset = unset, arr1 extends unknown[] | _ | unset = unset, arr2 extends unknown[] | _ | unset = unset, arr3 extends unknown[] | _ | unset = unset, arr4 extends unknown[] | _ | unset = unset, arr5 extends unknown[] | _ | unset = unset, arr6 extends unknown[] | _ | unset = unset, arr7 extends unknown[] | _ | unset = unset, arr8 extends unknown[] | _ | unset = unset, arr9 extends unknown[] | _ | unset = unset> = PartialApply<ZipWithFn<args>, [ | ||
arr0, | ||
@@ -532,3 +571,18 @@ arr1, | ||
]>; | ||
/** | ||
* Returns the length of a tuple | ||
* @param tuple - any tuple | ||
* @returns a number | ||
* @example | ||
* ```ts | ||
* type T0 = Call<Tuples.Length, [1, 2, 3]>; // 3 | ||
* type T1 = Eval<Tuples.Length, []>; 0 | ||
* type T2 = Eval<Tuples.Length, ['a']>; 1 | ||
* ``` | ||
*/ | ||
export type Length<tuple extends readonly any[] | _ | unset = unset> = PartialApply<LengthFn, [tuple]>; | ||
interface LengthFn extends Fn { | ||
return: this["args"] extends [infer tuple extends readonly any[], ...any] ? tuple["length"] : never; | ||
} | ||
export {}; | ||
} |
import { Call, Eval, Fn, PartialApply, unset, _ } from "../core/Core"; | ||
import { UnionToTuple } from "../helpers"; | ||
import { UnionToIntersection, UnionToTuple } from "../helpers"; | ||
import { Std } from "../std/Std"; | ||
@@ -62,3 +62,33 @@ import { Tuples } from "../tuples/Tuples"; | ||
} | ||
/** | ||
* `Unions.NonNullable` excludes null and undefined from the union type. | ||
* @param union - any union type. | ||
* @returns a union which is excluded by null and undefined. | ||
* @example | ||
* ```ts | ||
* type T0 = Call<Unions.NonNullable, "a" | 1 | null | undefined>; // 1 | "a" | ||
* type T1 = Pipe<"a" | 1 | null | undefined, [U.NonNullable]>; // 1 | "a" | ||
* type T2 = Eval<Unions.NonNullable<"a" | 1 | null | undefined>>; // 1 | "a" | ||
* ``` | ||
*/ | ||
export type NonNullable<union = unset> = PartialApply<NonNullableFn, [union]>; | ||
interface NonNullableFn extends Fn { | ||
return: this["arg0"] extends infer union ? Std._NonNullable<union> : never; | ||
} | ||
/** | ||
* `Unions.ToIntersection` turns a union type into an intersection type. | ||
* @param union - any union type. | ||
* @returns an intersection of all member of the union | ||
* @example | ||
* ```ts | ||
* type T0 = Call<Unions.ToIntersection, {a: string} | {b: number}>; // {a: string} & {b: number} | ||
* ``` | ||
*/ | ||
export type ToIntersection<union = unset> = PartialApply<ToIntersectionFn, [ | ||
union | ||
]>; | ||
interface ToIntersectionFn extends Fn { | ||
return: this["args"] extends [infer union, ...any] ? UnionToIntersection<union> : never; | ||
} | ||
export {}; | ||
} |
{ | ||
"name": "hotscript", | ||
"version": "1.0.8", | ||
"version": "1.0.9", | ||
"description": "Type-level madness", | ||
@@ -5,0 +5,0 @@ "type": "module", |
@@ -21,2 +21,4 @@ # Higher-Order TypeScript (HOTScript) | ||
[Run this as a TypeScript Playground](https://www.typescriptlang.org/play?#code/JYWwDg9gTgLgBAbzgBWGApgGjgFQK5gA26AztgMoxTAB2A5mXAHJ4gBG6UJcAvnAGZQIIOACIAFhBgkAxtTAxRAbgBQKgPTq4YKOhgxgnALTA6NaOhUwAnhji6SARjgBeFGnQAeFXDibfAHoA-D5wANqO2ABM2ADM2AAscYkAupihYaG++ESkAHQAsgCGYJ4s7JwkeQCCACa1nrEAfE3pvtkExFUAUhC0nqJ5oq1ZcJTU9FXkRMAwA0Mj7bid+cWl47QMeTgQ5RxQi+05XYUlZaz7VXUNjgAMLW1HK1OsoSkqTUpAA) | ||
```ts | ||
@@ -42,4 +44,6 @@ import { Pipe, Tuples, Strings, Numbers } from "hotscript"; | ||
[Run this as a TypeScript Playground](https://www.typescriptlang.org/play?#code/JYWwDg9gTgLgBAbzgYQIYBt0Bo4DEB2OAKgK5joCmAznAL5wBmUEIcARABYQxUDGUwMDDYBuAFBiA9JLhEOwGgrio4MAJ5gKAWkoA3CunbpUIAEYATVGwCEY4PhgUoDVLwpwAImXTBeqR3AUAB6O+OY0BIhicHBQFDAkUPgAXHAA2jDyVGlsqFAA5gAMbAC6OJkKOXlFpSXitBLqmrHUJOgwAIxwALwoGOgAPKTk1AB0ALKoYANe5L7+FAB8OGkdOABMOADMOAAsJYvi0jEnAHoA-I0a7nFUbTDrPX2YQ95juMYwk9OzPn6Oy3SazgmzgOzg+0OUhkJzgFyAA) | ||
```ts | ||
import { Call, Fn Tuples } from "hotscript"; | ||
import { Call, Fn, Tuples } from "hotscript"; | ||
@@ -60,3 +64,7 @@ // This is a type-level "lambda"! | ||
[Run this as a TypeScript Playground](https://www.typescriptlang.org/play?#code/JYWwDg9gTgLgBAbzgBWGApgGjgeQEYBW6AxjAM7YBCEEANugIYB2ZcAvnAGZQQhwBEACwjliUNDH4BuAFAyA9PLgAZdDADkrYr0hl0cMr32cArk1LAILODAg2ozMp2h9mcCIRLwYATwwAuGV8MOAAVCABBZABJZAYfWggGABMAHlCAPjgAXhQ0dFSZODDMIrgAbTLi-CJSMgA6HBBgGEofVOo6RhZ6gFEARxMGWjJUsh8QPDoMjNLi6s86+oiyMmAAcyZUpBA1FIYYBn9EOCZ0AHcAVT0oY5goE30ONlmq3EXyeoBlJgYAa3QAGEGHoACLodBgObzGpeBorNabbZwYDJY5ke7AJjrdgZMoAXRkGVkwX0UWi13QUByYUiMTiCSSaQQZUU8wAegB+Mqo9ETKa0WTFTjAKAYgByDF26Mx2KFcFoIJgkulBll61kL1kbIASmoTFAWIFSWEaSziry1eI5WVdodkgcjiczucAPomG53B5PeUisUwV2-VUY60asqKjGBqXoGWhzVSIA) | ||
```ts | ||
import { Pipe, Objects, Booleans } from "hotscript"; | ||
// Let's compose some functions to transform an object type: | ||
@@ -86,2 +94,27 @@ type ToAPIPayload<T> = Pipe< | ||
#### Parsing a route path | ||
[Run this as a TypeScript Playground](https://www.typescriptlang.org/play?#code/JYWwDg9gTgLgBAbzgBWGApgGjgeQEYBW6AxjAM7YDKMUwAdgOYVwDCE4EZ6AMugGYxsAFQCuYADbpmAWQCGMYgAs4AXzh8o7OACJFEcsVpgY2gNwAoczACeGOFCkBWOAF4UadAB5zcOAHo-X18APQB+Hx0-ES4oMj9PYAATAC4yGnoGAD4-SDS4hLpE9AAPZLoREDx0KEztTAiAbQjfalpGMgA6SglgGE9tP21M+qC4UQkpDoAxYHEYas9WjM7qWVgyAHVexX7+zOHmsbFJTrkwb1HfNg4uXgFPJsugpfaOoVoQXe04AB8dWoOTxa6Ve3XEvX6ySGI0uAF1ModAUFxic3hAAKp0YAQOgw3z4IikTpTTQgACidHSUjxuEIJHIHTOADVZOIRFILpc5Aodo8gdylB0tjAdto0m0GHU4OKMkingLFELtv1ypVqlLVVUaodfPDERFYeZMqYgA) | ||
https://user-images.githubusercontent.com/2315749/222081717-96217cd2-ac89-4e06-a942-17fbda717cd2.mp4 | ||
```ts | ||
import { Pipe, Objects, Strings, ComposeLeft, Tuples, Match } from "hotscript"; | ||
type res5 = Pipe< | ||
// ^? { id: string, index: number } | ||
"/users/<id:string>/posts/<index:number>", | ||
[ | ||
Strings.Split<"/">, | ||
Tuples.Filter<Strings.StartsWith<"<">>, | ||
Tuples.Map<ComposeLeft<[Strings.Trim<"<" | ">">, Strings.Split<":">]>>, | ||
Tuples.ToUnion, | ||
Objects.FromEntries, | ||
Objects.MapValues< | ||
Match<[Match.With<"string", string>, Match.With<"number", number>]> | ||
> | ||
] | ||
>; | ||
``` | ||
## TODO | ||
@@ -126,2 +159,6 @@ | ||
- [x] ToUnion | ||
- [x] ToIntersection | ||
- [x] Prepend | ||
- [x] Append | ||
- [x] Concat | ||
- [ ] Object | ||
@@ -135,3 +172,3 @@ - [x] Readonly | ||
- [ ] RequiredDeep | ||
- [ ] PartialDeep | ||
- [x] PartialDeep | ||
- [x] Update | ||
@@ -166,3 +203,5 @@ - [x] Record | ||
- [x] ExcludeBy | ||
- [x] NonNullable | ||
- [x] ToTuple | ||
- [x] ToIntersection | ||
- [ ] String | ||
@@ -169,0 +208,0 @@ - [x] Length |
170774
4440
253