From 9b4036d1fda25586a5866c8e77ba698f39d709f9 Mon Sep 17 00:00:00 2001 From: Beeno Tung Date: Mon, 30 Oct 2023 08:19:23 +0800 Subject: [PATCH] wip: recursively infer parser return type --- examples/infer-demo.ts | 7 +++++-- src/core.spec.ts | 13 ++++++++++++- src/core.ts | 8 ++++---- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/examples/infer-demo.ts b/examples/infer-demo.ts index 4e81f9a..4ddf9ca 100644 --- a/examples/infer-demo.ts +++ b/examples/infer-demo.ts @@ -29,7 +29,10 @@ console.log(parser.type) type Result = ParseResult type Post = Result['postList'][number] -// @ts-expect-error type PostStatus = Post['status'] -// TODO extract object field name without $suffix +function checkType(t: T) { + /* noop */ +} + +checkType<'active' | 'hidden'>(null as unknown as PostStatus) diff --git a/src/core.spec.ts b/src/core.spec.ts index 97ce951..65f1ad6 100644 --- a/src/core.spec.ts +++ b/src/core.spec.ts @@ -461,7 +461,7 @@ describe('object parser', () => { }`) } }) - it('should infer result type without $ flags', () => { + it('should infer result type without enums/nullable/optional flags', () => { let parser = inferFromSampleValue({ 'status_1$enums': ['a' as const, 'b' as const], 'status_2$enum': ['a' as const, 'b' as const], @@ -500,6 +500,17 @@ describe('object parser', () => { status_11?: undefined | null | 'a' | 'b' }>(result) }) + it('should recursively infer result type', () => { + let parser = inferFromSampleValue({ + a$nullable: { + b$optional: { + c$enums: ['a' as const, 'b' as const], + }, + }, + }) + let result = parser.parse({ a: { b: { c: 'a' } } }) + expect(result.a?.b?.c).to.equals('a') + }) }) describe('date parser', () => { diff --git a/src/core.ts b/src/core.ts index 9530614..614c697 100644 --- a/src/core.ts +++ b/src/core.ts @@ -1097,13 +1097,13 @@ type InferNullableField = { ? never : P extends `${string}$null${string}` ? never - : P]: O[P] + : P]: InferType } & { [P in keyof O as P extends `${infer H}$nullable${infer T}` ? `${H}${T}` : P extends `${infer H}$null${infer T}` ? `${H}${T}` - : never]: null | O[P] + : never]: null | InferType } type InferOptionalField = { @@ -1111,13 +1111,13 @@ type InferOptionalField = { ? never : P extends `${string}?${string}` ? never - : P]: O[P] + : P]: InferType } & { [P in keyof O as P extends `${infer H}$optional${infer T}` ? `${H}${T}` : P extends `${infer H}?${infer T}` ? `${H}${T}` - : never]?: O[P] + : never]?: InferType } type InferObjectType = InferOptionalField<