Skip to content

Commit 1c2ad87

Browse files
committed
Loose signature for index signature shapes
1 parent 0a83863 commit 1c2ad87

File tree

3 files changed

+33
-2
lines changed

3 files changed

+33
-2
lines changed

packages/zod/src/v4/classic/tests/object.test.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -516,3 +516,17 @@ test("zodtype assignability", () => {
516516
// @ts-expect-error
517517
z.object({ hello: z.number() }) satisfies z.ZodType<{ hello?: string | undefined }>;
518518
});
519+
520+
test("index signature in shape", () => {
521+
function makeZodObj<const T extends string>(key: T) {
522+
return z.looseObject({
523+
[key]: z.string(),
524+
});
525+
}
526+
527+
const schema = makeZodObj("foo");
528+
type schema = z.infer<typeof schema>;
529+
schema.parse({}).asdf;
530+
531+
expectTypeOf<schema>().toEqualTypeOf<Record<string, unknown>>();
532+
});

packages/zod/src/v4/core/schemas.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1527,7 +1527,7 @@ type OptionalOutSchema = { _zod: { optout: "optional" } };
15271527
type OptionalInSchema = { _zod: { optin: "optional" } };
15281528

15291529
export type $InferObjectOutput<T extends $ZodLooseShape, Extra extends Record<string, unknown>> = string extends keyof T
1530-
? object
1530+
? Record<string, unknown>
15311531
: keyof (T & Extra) extends never
15321532
? Record<string, never>
15331533
: util.Prettify<
@@ -1539,7 +1539,7 @@ export type $InferObjectOutput<T extends $ZodLooseShape, Extra extends Record<st
15391539
>;
15401540

15411541
export type $InferObjectInput<T extends $ZodLooseShape, Extra extends Record<string, unknown>> = string extends keyof T
1542-
? object
1542+
? Record<string, unknown>
15431543
: keyof (T & Extra) extends never
15441544
? Record<string, never>
15451545
: util.Prettify<

play.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,20 @@ console.dir(nativeEnumSchema.safeParse("a"), { depth: null }); // Valid
77
console.dir(nativeEnumSchema.safeParse("d"), { depth: null }); // Throws ZodError
88

99
z.file().mime([""]);
10+
11+
// function makeZodObj<const T extends string>(key: T) {
12+
// const a: string = "a";
13+
// const b: string = "b";
14+
// return z.looseObject({
15+
// [a]: z.string(),
16+
// [b]: z.number(),
17+
// });
18+
// }
19+
20+
function makeZodObj<K extends string>(key: K) {
21+
return z.record(z.literal(key), z.string());
22+
}
23+
24+
const schema = makeZodObj("foo");
25+
type schema = z.infer<typeof schema>;
26+
// { foo: string; }

0 commit comments

Comments
 (0)