From 408eb22c7f82b4e67ac70a659b6da831afc86ae0 Mon Sep 17 00:00:00 2001 From: Jason Kuhrt Date: Tue, 6 Sep 2022 18:01:13 -0400 Subject: [PATCH] feat: make types more readable (#127) --- package.json | 1 + pnpm-lock.yaml | 6 ++++++ src/data/types/Controller.ts | 17 +++++++++------- src/record/types/controller.ts | 36 +++++++++++++++++++--------------- 4 files changed, 37 insertions(+), 23 deletions(-) diff --git a/package.json b/package.json index c085f03..8158feb 100644 --- a/package.json +++ b/package.json @@ -46,6 +46,7 @@ "dependencies": { "lodash.ismatch": "^4.4.0", "remeda": "^1.0.0", + "ts-toolbelt": "^9.6.0", "zod": "^3.17.3" }, "devDependencies": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 463d531..1e93ac2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -31,6 +31,7 @@ specifiers: semver: 7.3.7 semver-utils: 1.1.4 ts-node: 10.9.1 + ts-toolbelt: ^9.6.0 tsd: 0.23.0 typescript: 4.8.2 vitest: 0.23.1 @@ -39,6 +40,7 @@ specifiers: dependencies: lodash.ismatch: 4.4.0 remeda: 1.0.0 + ts-toolbelt: 9.6.0 zod: 3.17.10 devDependencies: @@ -4034,6 +4036,10 @@ packages: yn: 3.1.1 dev: true + /ts-toolbelt/9.6.0: + resolution: {integrity: sha512-nsZd8ZeNUzukXPlJmTBwUAuABDe/9qtVDelJeT/qW0ow3ZS3BsQJtNkan1802aM9Uf68/Y8ljw86Hu0h5IUW3w==} + dev: false + /tsd/0.23.0: resolution: {integrity: sha512-dY4p7LbshRQ1hizr+xlbebgkfB0kT8wnQZW7LjBrOsmbws5mt1YYY4VSKoLYXyzYxObIOSQ3qns+tX8tP0Mz6g==} engines: {node: '>=14.16'} diff --git a/src/data/types/Controller.ts b/src/data/types/Controller.ts index 5b5ae69..34ecaaa 100644 --- a/src/data/types/Controller.ts +++ b/src/data/types/Controller.ts @@ -4,6 +4,7 @@ import { ObjectValues, OnlyStrings } from '../../lib/utils.js' import { RecordController } from '../../record/types/controller.js' import { StoredRecord } from '../../record/types/StoredRecord.js' import { StoredADT } from './Builder.js' +import { Any } from 'ts-toolbelt' export type SomeShortHandRecordSchemaDefs = Record @@ -67,9 +68,12 @@ export namespace DataController { // prettier-ignore export type DataController = - ADT & - ADTMethods & - RecordsMethods + Any.Compute< + ADT & + RecordsMethods & + ADTMethods, + 'flat' + > /** * Build up the API on the ADT itself: @@ -81,9 +85,9 @@ export type DataController = */ // prettier-ignore type ADTMethods = { + from: Any.Compute & StoredRecords.GetAdtLevelDecoderMethods> + to: Any.Compute & StoredRecords.GetAdtLevelEncoderMethods> schema: StoredRecords.ZodUnion - from: DecoderMethods<'json', Vs> & StoredRecords.GetAdtLevelDecoderMethods - to: EncoderMethods<'json', Vs> & StoredRecords.GetAdtLevelEncoderMethods } /** @@ -95,8 +99,7 @@ type ADTMethods = { * ``` */ export type RecordsMethods = { - [V in Vs[number] as V[`name`]]: RecordController - // [V in Vs[number] as V[`name`]]: V['schema'] + [V in Vs[number] as V[`name`]]: Any.Compute, 'flat'> } // Helpers diff --git a/src/record/types/controller.ts b/src/record/types/controller.ts index 7487227..7c5118e 100644 --- a/src/record/types/controller.ts +++ b/src/record/types/controller.ts @@ -4,6 +4,7 @@ import { OmitRequired, Rest } from '../../lib/utils.js' import { z } from '../../lib/z/index.js' import { SomeDecodeOrThrowJson, SomeDecoderJson, SomeDefaultsProvider, SomeEncoderJson } from './internal.js' import { SomeStoredRecord, StoredRecord } from './StoredRecord.js' +import { Any } from 'ts-toolbelt' export type SomeRecord = { _tag: string @@ -67,16 +68,17 @@ type DecoderMethods = { } export namespace RecordController { - export type CreateFromSchema = CreateFromStoredRecord< - StoredRecord.AddSchema> + export type CreateFromSchema = Any.Compute< + CreateFromStoredRecord>>, + 'flat' > - export type CreateFromSchemaDef< - Name extends SomeName, - SchemaDef extends SomeSchemaDef - > = CreateFromStoredRecord>> + export type CreateFromSchemaDef = Any.Compute< + CreateFromStoredRecord>>, + 'flat' + > - export type CreateFromStoredRecord = RecordController<[R], R> + type CreateFromStoredRecord = RecordController<[R], R> export type GetConstructorInput = ApplyDefaults< V['defaults'], @@ -95,16 +97,15 @@ export type RecordController, changes: Partial>>): StoredRecord.GetType + update(record: StoredRecord.GetType, changes: Any.Compute>>>): StoredRecord.GetType /** * Decoders for this record. Decoders are used to transform other representations of your record back into a record instance. */ - from: { + from: Any.Compute<{ /** * Decode JSON into this record. If it fails for any reason, returns `null`. * @@ -117,21 +118,21 @@ export type RecordController - } & Decoders + } & Decoders> // & { // [I in IndexKeys as AsString]: Decoder,V> // } /** * Encoders for this record. Encoders are used to transform your record into another representation. */ - to: { + to: Any.Compute<{ /** * Encode an instance of this record into JSON. * * @remarks This is a built in encoder. */ json(record: StoredRecord.GetType): string - } & Encoders + } & Encoders> /** * Strict predicate/type guard for this record. * @@ -168,15 +169,18 @@ export type RecordController): StoredRecord.GetType + create(input?: Any.Compute>): StoredRecord.GetType } : { /** * TODO */ - create(input: RecordController.GetConstructorInput): StoredRecord.GetType + create(input: Any.Compute>): StoredRecord.GetType }) & - R[`extensions`] + R[`extensions`] & + { + schema: R['schema'] + } export type ApplyDefaults = { [K in keyof Input as K extends keyof Defaults ? never : K]: Input[K]