Skip to content

Commit d81a286

Browse files
committed
fix(npm-zod): storing union types in AtomMut rather than primitive containers
1 parent 863aa8f commit d81a286

File tree

3 files changed

+26
-17
lines changed

3 files changed

+26
-17
lines changed

packages/npm-zod/src/index.test-d.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ test("right types for basic schema", async () => {
99
readonly: z.string().readonly(),
1010
nullable: z.string().nullable(),
1111
optional: z.string().optional(),
12+
nullishNumber: z.number().nullish(),
13+
nullishBoolean: z.boolean().nullish(),
1214
})
1315
const model = reatomZod(schema)
1416
type InferedSchema = z.infer<typeof schema>;
@@ -18,6 +20,8 @@ test("right types for basic schema", async () => {
1820
expectTypeOf(model.readonly).toEqualTypeOf<InferedSchema['readonly']>()
1921
expectTypeOf(model.nullable).toEqualTypeOf<AtomMut<InferedSchema['nullable']>>()
2022
expectTypeOf(model.optional).toEqualTypeOf<AtomMut<InferedSchema['optional']>>()
23+
expectTypeOf(model.nullishNumber).toEqualTypeOf<AtomMut<InferedSchema['nullishNumber']>>()
24+
expectTypeOf(model.nullishBoolean).toEqualTypeOf<AtomMut<InferedSchema['nullishBoolean']>>()
2125
})
2226

2327
test("right types for catch", async () => {
@@ -60,17 +64,17 @@ test("right types for brands", async () => {
6064

6165
const objectSchema = z.object({
6266
brand: z.object({
63-
kek: z.string().brand('foo'),
64-
}).nullish().brand('foo'),
65-
brand2: z.object({}).nullish().brand('bar'),
67+
kek: z.string().nullable().brand('foo'),
68+
}).brand('foo'),
69+
brand2: z.object({}).brand('bar'),
6670
})
6771

6872
const objectModel = reatomZod(objectSchema)
69-
type InferedObjectSchema = z.infer<typeof objectSchema>
73+
type InferedObjectSchema = z.infer<typeof objectSchema>;
7074

7175
expectTypeOf(objectModel).toEqualTypeOf<{
7276
brand: {
73-
kek: AtomMut<InferedObjectSchema['brand']['kek']>
77+
kek: AtomMut<InferedObjectSchema['brand']['kek'] | null>
7478
} & z.BRAND<'foo'>,
7579
brand2: InferedObjectSchema['brand2']
7680
}>();

packages/npm-zod/src/index.test.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,11 @@ import { reatomZod } from "./";
66

77
test("base API", async () => {
88
const model = reatomZod(
9-
z.object({ n: z.number(), s: z.string(), readonly: z.string().readonly() }),
9+
z.object({
10+
n: z.number(),
11+
s: z.string(),
12+
readonly: z.string().readonly(),
13+
}),
1014
{
1115
sync: () => {
1216
track(parseAtoms(ctx, model));

packages/npm-zod/src/index.ts

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ export interface SetAtom<T> extends ZodAtom<[T]>, ReatomSetAtom<T> {}
4242
export interface LinkedListAtom<Params extends any[] = any[], Model extends Rec = Rec> extends ZodAtom<Array<Model>>, ReatomLinkedListAtom<Params, Model> {}
4343

4444
type DistributeIntersection<U, T> = U extends any ? U & T : never;
45-
type Example = DistributeIntersection<number | string | boolean, z.BRAND<'test'>>;
4645

4746
export type ZodAtomization<T extends z.ZodFirstPartySchemaTypes, Union = never, Intersection = unknown> = T extends z.ZodAny
4847
? AtomMut<(any & Intersection) | Union>
@@ -63,11 +62,11 @@ export type ZodAtomization<T extends z.ZodFirstPartySchemaTypes, Union = never,
6362
: T extends z.ZodLiteral<infer T>
6463
? (T & Intersection) | Union
6564
: T extends z.ZodBoolean
66-
? never extends Union
65+
? [Union] extends [never]
6766
? BooleanAtom
6867
: AtomMut<(boolean & Intersection) | Union>
6968
: T extends z.ZodNumber
70-
? never extends Union
69+
? [Union] extends [never]
7170
? NumberAtom
7271
: AtomMut<(number & Intersection) | Union>
7372
: T extends z.ZodBigInt
@@ -83,29 +82,31 @@ export type ZodAtomization<T extends z.ZodFirstPartySchemaTypes, Union = never,
8382
: T extends z.ZodTuple<infer Tuple>
8483
? AtomMut<(z.infer<Tuple[number]> & Intersection) | Union>
8584
: T extends z.ZodObject<infer Shape>
86-
? never extends Union
85+
? [Union] extends [never]
8786
? {
8887
[K in keyof Shape]: ZodAtomization<Shape[K]>;
8988
} & Intersection
90-
: AtomMut<(Shape & Intersection) | Union>
89+
: AtomMut<({
90+
[K in keyof Shape]: ZodAtomization<Shape[K]>
91+
} & Intersection) | Union>
9192
: T extends z.ZodRecord<infer KeyType, infer ValueType>
92-
? never extends Union
93+
? [Union] extends [never]
9394
? RecordAtom<Record<z.infer<KeyType>, ZodAtomization<ValueType>>>
9495
: AtomMut<(Record<z.infer<KeyType>, ZodAtomization<ValueType>> & Intersection) | Union>
9596
: T extends z.ZodMap<infer KeyType, infer ValueType>
96-
? never extends Union
97+
? [Union] extends [never]
9798
? MapAtom<z.infer<KeyType>, ZodAtomization<ValueType>>
9899
: AtomMut<(Map<z.infer<KeyType>, ZodAtomization<ValueType>> & Intersection) | Union>
99100
: T extends z.ZodSet<infer ValueType>
100-
? never extends Union
101+
? [Union] extends [never]
101102
? SetAtom<z.infer<ValueType>>
102103
: AtomMut<(Set<z.infer<ValueType>> & Intersection) | Union>
103104
: T extends z.ZodEnum<infer Enum>
104-
? never extends Union
105+
? [Union] extends [never]
105106
? EnumAtom<Enum[number]>
106107
: AtomMut<(Enum[number] & Intersection) | Union>
107108
: T extends z.ZodNativeEnum<infer Enum>
108-
? never extends Union
109+
? [Union] extends [never]
109110
? // @ts-expect-error шо?
110111
EnumAtom<Enum[keyof Enum]>
111112
: AtomMut<(Enum[keyof Enum] & Intersection) | Union>
@@ -128,7 +129,7 @@ export type ZodAtomization<T extends z.ZodFirstPartySchemaTypes, Union = never,
128129
: T extends z.ZodUnion<infer T>
129130
? AtomMut<DistributeIntersection<z.infer<T[number]>, Intersection> | Union>
130131
: T extends z.ZodDiscriminatedUnion<infer K, infer T>
131-
? never extends Union
132+
? [Union] extends [never]
132133
? T extends Array<z.ZodObject<infer Shape>>
133134
? Atom<{
134135
[K in keyof Shape]: ZodAtomization<Shape[K]>;

0 commit comments

Comments
 (0)