Skip to content

feat: create recordWithPatterns schema#1165

Open
EskiMojo14 wants to merge 5 commits intoopen-circle:mainfrom
EskiMojo14:object-with-pattern
Open

feat: create recordWithPatterns schema#1165
EskiMojo14 wants to merge 5 commits intoopen-circle:mainfrom
EskiMojo14:object-with-pattern

Conversation

@EskiMojo14
Copy link
Member

@EskiMojo14 EskiMojo14 commented Apr 20, 2025

fixes #1159

const Schema = v.recordWithPatterns(
  [
    [
      v.pipe(v.string(), v.regex(/^foo\(.+\)$/)),
      v.pipe(v.string(), v.maxLength(1)),
    ],
    [
      v.pipe(v.string(), v.regex(/^bar\(.+\)$/)),
      v.pipe(v.string(), v.maxLength(10)),
    ],
  ],
  v.number(),
);

Also includes proper index signatures for strongly typed keys, e.g.

const FooKeySchema = v.custom<`foo(${string}`>(
  (arg) => typeof arg === "string" && /^foo\(.+\)$/.test(arg),
);

const Schema = v.recordWithPatterns([[FooKeySchema, v.string()]], v.number());

const parsed = v.parse(Schema, { "foo(x)": "x", x: 1 });

parsed["foo(x)"]; // string
parsed.x; // number

@vercel
Copy link

vercel bot commented Apr 20, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
valibot ✅ Ready (Inspect) Visit Preview 💬 Add feedback Apr 22, 2025 10:11am

@fabian-hiller
Copy link
Member

Thank you for creating this PR! Do you know if Zod offers such a schema? How about calling it recordWithPatterns or templateRecord to better match our record schema? Is the second argument, the wildcard schema, necessary? Maybe it simplifies the API if we ask users to add this to the first argument.

@EskiMojo14
Copy link
Member Author

Do you know if Zod offers such a schema?

not to my knowledge, no - JSON schema has patternProperties which is similar

How about calling it recordWithPatterns or templateRecord to better match our record schema?

sure, makes sense

Is the second argument, the wildcard schema, necessary? Maybe it simplifies the API if we ask users to add this to the first argument.

what would be the desired behaviour if a key doesn't match any of the patterns?

@EskiMojo14
Copy link
Member Author

EskiMojo14 commented Apr 22, 2025

Ah, the rest argument is necessary, because these two types behave differently:

type Unmerged = {
    [key: `foo(${string})`]: string;
    [key: `bar(${string})`]: number;
} & {
    [key: string]: boolean;
}

type Merged = {
    [key: `foo(${string})`]: string;
    [key: `bar(${string})`]: number;
    [key: string]: boolean;
}

in Merged, the string index signature overrides all of the others.

edit: hmm, the below works, so we could just avoid calling Prettify to merge the intersection:

type Unmerged = {
    [key: `foo(${string})`]: string;
} & {
    [key: `bar(${string})`]: number;
} & {
    [key: string]: boolean;
}

it's kinda ugly, but 🤷🏻

@EskiMojo14 EskiMojo14 changed the title feat: create objectWithPatterns schema feat: create recordWithPatterns schema Apr 22, 2025
@EskiMojo14
Copy link
Member Author

EskiMojo14 commented Apr 22, 2025

that does still leave the question of what to do when a key doesn't match any of the patterns:

const parsed = v.parse(
  v.recordWithPatterns([
    [v.pipe(v.string(), v.startsWith("foo-")), v.string()],
  ]),
  { "foo-allowed": "hi", notAllowed: true },
);
// loose - { 'foo-allowed': 'hi', notAllowed: true }
// strip - { 'foo-allowed': 'hi' }
// strict - error
// rest - validate against rest, error if not match

@vercel
Copy link

vercel bot commented Jan 24, 2026

@EskiMojo14 is attempting to deploy a commit to the Open Circle Team on Vercel.

A member of the Team first needs to authorize it.

@dosubot dosubot bot added the size:XXL This PR changes 1000+ lines, ignoring generated files. label Jan 24, 2026
@pkg-pr-new
Copy link

pkg-pr-new bot commented Jan 24, 2026

Open in StackBlitz

npm i https://pkg.pr.new/valibot@1165

commit: 4f7bee8

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL This PR changes 1000+ lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Validate value based on key format

2 participants