Skip to content

Commit d62dcc8

Browse files
fix(zui): catchall inference (#612)
Co-authored-by: François Levasseur <francois.levasseur@botpress.com>
1 parent 39d14cb commit d62dcc8

File tree

4 files changed

+24
-10
lines changed

4 files changed

+24
-10
lines changed

zui/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@bpinternal/zui",
3-
"version": "0.22.4",
3+
"version": "0.22.5",
44
"description": "A fork of Zod with additional features",
55
"type": "module",
66
"source": "./src/index.ts",

zui/src/z/types/object/index.ts

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { unique } from '../../utils'
1+
import { unique, ValueOf } from '../../utils'
22
import {
33
ZodArray,
44
ZodEnum,
@@ -49,7 +49,8 @@ export type mergeTypes<A, B> = {
4949
export type objectOutputType<
5050
Shape extends ZodRawShape,
5151
UnknownKeys extends UnknownKeysParam = UnknownKeysParam,
52-
> = objectUtil.flatten<objectUtil.addQuestionMarks<baseObjectOutputType<Shape>>> & UnknownKeysOutputType<UnknownKeys>
52+
> = UnknownKeysOutputType<UnknownKeys, Shape> &
53+
objectUtil.flatten<objectUtil.addQuestionMarks<baseObjectOutputType<Shape>>>
5354

5455
export type baseObjectOutputType<Shape extends ZodRawShape> = {
5556
[k in keyof Shape]: Shape[k]['_output']
@@ -58,19 +59,20 @@ export type baseObjectOutputType<Shape extends ZodRawShape> = {
5859
export type objectInputType<
5960
Shape extends ZodRawShape,
6061
UnknownKeys extends UnknownKeysParam = UnknownKeysParam,
61-
> = objectUtil.flatten<baseObjectInputType<Shape>> & UnknownKeysInputType<UnknownKeys>
62+
> = objectUtil.flatten<baseObjectInputType<Shape>> & UnknownKeysInputType<UnknownKeys, Shape>
63+
6264
export type baseObjectInputType<Shape extends ZodRawShape> = objectUtil.addQuestionMarks<{
6365
[k in keyof Shape]: Shape[k]['_input']
6466
}>
6567

66-
export type UnknownKeysInputType<T extends UnknownKeysParam> = T extends ZodTypeAny
67-
? { [k: string]: T['_input'] }
68+
export type UnknownKeysInputType<T extends UnknownKeysParam, S extends ZodRawShape> = T extends ZodTypeAny
69+
? { [k: string]: T['_input'] | ValueOf<baseObjectInputType<S>> } // extra properties cannot contradict the main properties
6870
: T extends 'passthrough'
6971
? { [k: string]: unknown }
7072
: {}
7173

72-
export type UnknownKeysOutputType<T extends UnknownKeysParam> = T extends ZodTypeAny
73-
? { [k: string]: T['_output'] }
74+
export type UnknownKeysOutputType<T extends UnknownKeysParam, S extends ZodRawShape> = T extends ZodTypeAny
75+
? { [k: string]: T['_output'] | ValueOf<baseObjectOutputType<S>> } // extra properties cannot contradict the main properties
7476
: T extends 'passthrough'
7577
? { [k: string]: unknown }
7678
: {}

zui/src/z/types/object/object.test.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,18 @@ test('catchall inference', () => {
113113
.catchall(z.number())
114114

115115
const d1 = o1.parse({ first: 'asdf', num: 1243 })
116-
util.assertEqual<number, (typeof d1)['asdf']>(true)
117-
util.assertEqual<string, (typeof d1)['first']>(true)
116+
117+
const fnInput = (input: z.input<typeof o1>) => {}
118+
const fnOutput = (input: z.output<typeof o1>) => {}
119+
120+
fnInput({ first: 'asdf', num: 1243 })
121+
fnOutput({ first: 'asdf', num: 1243 })
122+
123+
const prop1 = d1.first
124+
const prop2 = d1.num
125+
126+
util.assertEqual<string, typeof prop1>(true)
127+
util.assertEqual<string | number | undefined, typeof prop2>(true)
118128
})
119129

120130
test('catchall overrides strict', () => {

zui/src/z/utils.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
export type ValueOf<T> = T[keyof T]
2+
13
export const unique = <T>(arr: T[]): T[] => {
24
return Array.from(new Set(arr))
35
}

0 commit comments

Comments
 (0)