valibot icon indicating copy to clipboard operation
valibot copied to clipboard

v.record numbers as keys

Open dxptqhtlutehvlyxcmtg opened this issue 1 year ago • 1 comments

We're getting a lot of use out of this library, thank you for it. Would it be possible for v.record() to match TS in allowing numbers as keys?

const x: Record<number, string> = {
  1: 'value',
};

It seems like v.record only accepts string-like keys, so there's no way to create such a schema currently.

dxptqhtlutehvlyxcmtg avatar Aug 02 '24 00:08 dxptqhtlutehvlyxcmtg

I would like to support it, but there is a problem. Object keys are automatically converted to strings. It is technically impossible to know if it was entered as a number or a string. So we can't reliably validate it.

Also, the "same" key entered once as a number and once as a string is treated as equal and overwrites each other. For example, { 123: 'foo', '123': 'bar' } results in { 123: 'bar' }.

Here is a workaround that may work for you in the meantime. Checkout this playground.

import * as v from 'valibot';

const Schema = v.record(
  v.pipe(v.string(), v.decimal(), v.transform(Number)),
  v.string(),
);

type Output = v.InferOutput<typeof Schema>; // { [x: number]: string }

fabian-hiller avatar Aug 02 '24 08:08 fabian-hiller