From a8003da29ccf6a1a7418a19c4585fefe74aad852 Mon Sep 17 00:00:00 2001 From: FerbDev Date: Sun, 25 Feb 2024 19:35:54 -0300 Subject: [PATCH 1/2] Add MutablePrimitives.ts for cases when create editable object --- src/MutablePrimitives.ts | 30 ++++++++++++ src/index.ts | 3 +- tests/MutablePrimitives.test.ts | 81 +++++++++++++++++++++++++++++++++ 3 files changed, 113 insertions(+), 1 deletion(-) create mode 100644 src/MutablePrimitives.ts create mode 100644 tests/MutablePrimitives.test.ts diff --git a/src/MutablePrimitives.ts b/src/MutablePrimitives.ts new file mode 100644 index 0000000..26e55c3 --- /dev/null +++ b/src/MutablePrimitives.ts @@ -0,0 +1,30 @@ +/* eslint-disable @typescript-eslint/ban-types */ +type Methods = { + [P in keyof T]: T[P] extends Function ? P : never; +}[keyof T]; + +type MethodsAndProperties = { [key in keyof T]: T[key] }; + +type NonReadonly = { + -readonly [P in keyof T]: T[P]; +}; + +type Properties = Omit>, Methods>; + +type PrimitiveTypes = string | number | boolean | Date | undefined | null; + +type ValueObjectValue = T extends PrimitiveTypes + ? T + : T extends { value: infer U } + ? U + : T extends Array<{ value: infer U }> + ? U[] + : T extends Array + ? Array> + : T extends { [K in keyof Properties]: infer U } + ? { [K in keyof Properties]: ValueObjectValue[K]> } + : never; + +export type MutablePrimitives = { + [key in keyof Properties]: ValueObjectValue; +}; \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index 6e993fc..96cc1b3 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,3 +1,4 @@ import { Primitives } from "./Primitives"; +import { MutablePrimitives } from "./MutablePrimitives"; -export { Primitives }; +export { Primitives, MutablePrimitives }; diff --git a/tests/MutablePrimitives.test.ts b/tests/MutablePrimitives.test.ts new file mode 100644 index 0000000..2ad8906 --- /dev/null +++ b/tests/MutablePrimitives.test.ts @@ -0,0 +1,81 @@ +import { expectTypeOf } from "expect-type"; +import { MutablePrimitives } from "../src"; +import { Course } from "./Course"; +import { DeliveryInfo } from "./DeliveryInfo"; +import { Learner } from "./Learner"; +import { Product } from "./Product"; +import { User } from "./User"; +import { Video } from "./Video"; + +describe("MutablePrimitives", () => { + it("should ensure to only return primitive properties excluding methods", () => { + type actualPrimitives = MutablePrimitives; + + type expectedPrimitives = { + courseId: string; + }; + + expectTypeOf().toEqualTypeOf(); + }); + + it("should get primitive array type from value object array", () => { + type actualPrimitives = MutablePrimitives; + + type expectedPrimitives = { + enrolledCourses: string[]; + }; + + expectTypeOf().toEqualTypeOf(); + }); + + it("should generate nested primitive object", () => { + type actualPrimitives = MutablePrimitives; + + type expectedPrimitives = { + address: { + city: string; + street: string; + number: number; + }; + }; + + expectTypeOf().toEqualTypeOf(); + }); + + it("should generate nested primitive type from array of value objects prop", () => { + type actualPrimitives = MutablePrimitives; + + type expectedPrimitives = { + addresses: { + city: string; + street: string; + number: number; + }[]; + }; + + expectTypeOf().toEqualTypeOf(); + }); + + it("should get primitive type in case it is not a value object", () => { + type actualPrimitives = MutablePrimitives; + + type expectedPrimitives = { + active: boolean; + createdAt: Date; + }; + + expectTypeOf().toEqualTypeOf(); + }); + + it("should infer the optional properties", () => { + type actualPrimitives = MutablePrimitives