Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to use a template literal type as a record() key value #291

Closed
genki opened this issue Dec 10, 2023 · 8 comments
Closed

Unable to use a template literal type as a record() key value #291

genki opened this issue Dec 10, 2023 · 8 comments
Assignees
Labels
enhancement New feature or request priority This has priority workaround Workaround fixes problem

Comments

@genki
Copy link
Contributor

genki commented Dec 10, 2023

I have tried to use the template literal type for a key of the record schema like this:

type Key = `${string}-${number}`;
const KeySchema = special<Key>((key:string) => {
  const parts = key.split("-");
  const num = parts.unshift();
  if (Number.isNaN(Number(num))) return false;
  const str = parts.join('-');
  if (typeof str !== "string") return false;
  return true;
});

const FooSchema = record(KeySchema, string());

But the type error happened at the last line:

No overload matches this call.
  The last overload gave the following error.
    Argument of type 'SpecialSchema<`${string}-${number}`, `${string}-${number}`>' is not assignable to parameter of type 'RecordKey'.
      Type 'SpecialSchema<`${string}-${number}`, `${string}-${number}`>' is not assignable to type 'StringSchema<string | number | symbol>'.
        Type 'SpecialSchema<`${string}-${number}`, `${string}-${number}`>' is not assignable to type '{ type: "string"; message: ErrorMessage; pipe: Pipe<string>; }'.
          Types of property 'type' are incompatible.
            Type '"special"' is not assignable to type '"string"'.

Here is the playground that tests this.
https://stackblitz.com/edit/typescript-c4dusa?file=index.ts

Is there proper a way to do this?

@fabian-hiller
Copy link
Owner

custom is a pipeline validation an not a schema. special is probably the correct schema for this use case but at the moment it is not supported with record. I will investigate if it is possible to support special. Until then, I recommend using string:

import * as v from 'valibot';

const KeySchema = v.string([
  v.custom((key) => {
    const parts = key.split('-');
    const num = parts.unshift();
    if (Number.isNaN(Number(num))) return false;
    const str = parts.join('-');
    if (typeof str !== 'string') return false;
    return true;
  }),
]);

const FooSchema = v.record(KeySchema, v.string());

@fabian-hiller fabian-hiller self-assigned this Dec 10, 2023
@fabian-hiller fabian-hiller added enhancement New feature or request workaround Workaround fixes problem priority This has priority labels Dec 10, 2023
@genki
Copy link
Contributor Author

genki commented Dec 10, 2023

@fabian-hiller Sorry I have mistakenly post an old example.
Now I have corrected it.

@fabian-hiller
Copy link
Owner

fabian-hiller commented Dec 10, 2023

As I wrote special is the right schema for this, but currently not supported by record. If it is possible I will fix this with the next minor version.

import * as v from 'valibot';

type Key = `${string}-${number}`;
const KeySchema = v.special<Key>((key) => {
  if (typeof key !== 'string') return false;
  const parts = key.split('-');
  const num = parts.unshift();
  if (Number.isNaN(Number(num))) return false;
  const str = parts.join('-');
  if (typeof str !== 'string') return false;
  return true;
});

// Not supported in <= v0.23.0
const FooSchema = v.record(KeySchema, v.string());

@genki
Copy link
Contributor Author

genki commented Dec 10, 2023

@fabian-hiller
Thanks! I understand :)
Is it good to remain open this issue until the solution would come?

@fabian-hiller
Copy link
Owner

Yes, please leave it open. I will probably work on it later or tomorrow.

@fabian-hiller
Copy link
Owner

fabian-hiller commented Dec 10, 2023

Fixed. As soon as v0.24.0 is available, I will close this issue. Thank you for your contribution!

@genki
Copy link
Contributor Author

genki commented Dec 10, 2023

@fabian-hiller
Thanks! I have confirmed the latest code solves this issue.

@genki genki closed this as completed Dec 10, 2023
@fabian-hiller
Copy link
Owner

v0.24.0 is available.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request priority This has priority workaround Workaround fixes problem
Projects
None yet
Development

No branches or pull requests

2 participants