From ab328f2cb5a4583ed6c5a80e530518dcc29576ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Sun, 28 Jan 2024 01:08:15 +0100 Subject: [PATCH] Util refactoring --- src/util.ts | 64 ------------------------- src/util/class.ts | 101 ++++++++++++++++++++++++++++++++++++++++ src/util/effect.ts | 26 +++++++++++ src/util/index.ts | 4 ++ src/util/inheritance.ts | 40 ++++++++++++++++ src/util/misc.ts | 3 ++ 6 files changed, 174 insertions(+), 64 deletions(-) delete mode 100644 src/util.ts create mode 100644 src/util/class.ts create mode 100644 src/util/effect.ts create mode 100644 src/util/index.ts create mode 100644 src/util/inheritance.ts create mode 100644 src/util/misc.ts diff --git a/src/util.ts b/src/util.ts deleted file mode 100644 index 338309f..0000000 --- a/src/util.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { Effect, pipe } from "effect" -import { AbstractClass, Class as ConcreteClass } from "type-fest" -import { z } from "zod" - - -export function identity(value: T) { - return value -} - - -export type ClassType = "AbstractClass" | "Class" - -export type Class< - Type extends ClassType, - T, - Arguments extends unknown[] = any[], -> = ( - Type extends "AbstractClass" - ? AbstractClass - : Type extends "Class" - ? ConcreteClass - : never -) - -export type GetClassType = ( - C extends ConcreteClass - ? "Class" - : C extends AbstractClass - ? "AbstractClass" - : never -) - - -/** - * Represents the static members of a class. - * @template C - The class type. - */ -export type StaticMembers = { - [Key in keyof C as Key extends "prototype" ? never : Key]: C[Key] -} - - -/** - * Parses a value using a ZodType schema wrapped in an Effect monad. - * - * @param schema - The ZodType schema to use for parsing. - * @param args - The arguments to pass to the `safeParseAsync` method of the schema. - * @returns An Effect monad representing the parsing result. - */ -export const parseZodTypeEffect = < - Output, - Input, ->( - schema: z.ZodType, - ...args: Parameters -) => pipe( - Effect.promise(() => schema.safeParseAsync(...args)), - - Effect.flatMap(response => - response.success - ? Effect.succeed(response.data) - : Effect.fail(response.error) - ), -) diff --git a/src/util/class.ts b/src/util/class.ts new file mode 100644 index 0000000..616f709 --- /dev/null +++ b/src/util/class.ts @@ -0,0 +1,101 @@ +import { AbstractClass, Class as ConcreteClass } from "type-fest" + + +/** + * Represents the possible types of a class. + */ +export type ClassType = "AbstractClass" | "Class" + +/** + * Represents a class based on the specified type. + * @template Type - The type of the class ("AbstractClass" or "Class"). + * @template T - The type parameter of the class. + * @template Arguments - The type of arguments the class constructor takes. + */ +export type Class< + Type extends ClassType, + T, + Arguments extends unknown[] = any[], +> = ( + Type extends "AbstractClass" + ? AbstractClass + : Type extends "Class" + ? ConcreteClass + : never +) + +/** + * Gets the type of a class (either "Class" or "AbstractClass"). + * @template C - The class type to determine. + */ +export type GetClassType = ( + C extends ConcreteClass + ? "Class" + : C extends AbstractClass + ? "AbstractClass" + : never +) + +/** + * Represents an array of instances corresponding to the provided classes. + * @template Classes - An array of classes extending AbstractClass. + */ +export type ClassesInstances[]> = ( + Classes extends [infer Class, ...infer Rest] + ? Class extends AbstractClass + ? Rest extends AbstractClass[] + ? [InstanceType, ...ClassesInstances] + : never + : never + : [] +) + +/** + * Represents an intersection of instances of the provided classes. + * @template Classes - An array of classes extending AbstractClass. + */ +export type ClassesInstancesIntersection[]> = ( + Classes extends [infer Class, ...infer Rest] + ? Class extends AbstractClass + ? Rest extends AbstractClass[] + ? InstanceType & ClassesInstancesIntersection + : never + : never + : {} +) + +/** + * Represents the static members of a class. + * @template Class - A class extending AbstractClass. + */ +export type StaticMembers> = ( + Omit +) + +/** + * Represents an array of static members corresponding to the provided classes. + * @template Classes - An array of classes extending AbstractClass. + */ +export type ClassesStaticMembers[]> = ( + Classes extends [infer Class, ...infer Rest] + ? Class extends AbstractClass + ? Rest extends AbstractClass[] + ? [StaticMembers, ...ClassesStaticMembers] + : never + : never + : [] +) + +/** + * Represents an intersection of static members of the provided classes. + * @template Classes - An array of classes extending AbstractClass. + */ +export type ClassesStaticMembersIntersection[]> = ( + Classes extends [infer Class, ...infer Rest] + ? Class extends AbstractClass + ? Rest extends AbstractClass[] + ? StaticMembers & ClassesStaticMembersIntersection + : never + : never + : {} +) diff --git a/src/util/effect.ts b/src/util/effect.ts new file mode 100644 index 0000000..f7ce9eb --- /dev/null +++ b/src/util/effect.ts @@ -0,0 +1,26 @@ +import { Effect, pipe } from "effect" +import { z } from "zod" + + +/** + * Parses a value using a ZodType schema wrapped in an Effect monad. + * + * @param schema - The ZodType schema to use for parsing. + * @param args - The arguments to pass to the `safeParseAsync` method of the schema. + * @returns An Effect monad representing the parsing result. + */ +export const parseZodTypeEffect = < + Output, + Input, +>( + schema: z.ZodType, + ...args: Parameters +) => pipe( + Effect.promise(() => schema.safeParseAsync(...args)), + + Effect.flatMap(response => + response.success + ? Effect.succeed(response.data) + : Effect.fail(response.error) + ), +) diff --git a/src/util/index.ts b/src/util/index.ts new file mode 100644 index 0000000..f7d0c08 --- /dev/null +++ b/src/util/index.ts @@ -0,0 +1,4 @@ +export * from "./class" +export * from "./effect" +export * from "./inheritance" +export * from "./misc" diff --git a/src/util/inheritance.ts b/src/util/inheritance.ts new file mode 100644 index 0000000..a179d78 --- /dev/null +++ b/src/util/inheritance.ts @@ -0,0 +1,40 @@ +/** + * Represents the common keys between two types. + * @template A - The first type. + * @template B - The second type. + */ +export type CommonKeys = Extract + +/** + * Merges an inheritance tree defined by an array of types, considering overrides. + * @template T - An array of types representing the inheritance tree. + */ +export type MergeInheritanceTree = ( + T extends [infer Super, infer Self, ...infer Rest] + ? Pick> extends Pick> + ? MergeInheritanceTree<[ + Omit> & Self, + ...Rest, + ]> + : never + : T extends [infer Self] + ? Self + : void +) + +/** + * Merges an inheritance tree defined by an array of types without allowing overrides. + * @template T - An array of types representing the inheritance tree. + */ +export type MergeInheritanceTreeWithoutOverriding = ( + T extends [infer Super, infer Self, ...infer Rest] + ? Pick> extends Pick> + ? MergeInheritanceTreeWithoutOverriding<[ + Super & Self, + ...Rest, + ]> + : never + : T extends [infer Self] + ? Self + : void +) diff --git a/src/util/misc.ts b/src/util/misc.ts new file mode 100644 index 0000000..f381be2 --- /dev/null +++ b/src/util/misc.ts @@ -0,0 +1,3 @@ +export function identity(value: T) { + return value +}