valibot: Optional returns the string | undefined type even with the default value set

I use the following schema:

export const ConfigSchema = v.object({
    logger: v.object({
        level: v.optional(v.string(), "test"),
        path: v.optional(v.nullable(v.string()), null)
    })
})

When I try to pass the value after validation, I get an error like: TS2345: Argument of type 'string | undefined' is not assignable to parameter of type 'string'.   Type 'undefined' is not assignable to type 'string'.

Type: level?: string | undefined

This is a strange behavior, because when the default value is set, either the value from json or the default value will be returned to me.

About this issue

  • Original URL
  • State: closed
  • Created 7 months ago
  • Comments: 30 (14 by maintainers)

Commits related to this issue

Most upvoted comments

@fabian-hiller The problem was indeed solved in version 2.24.1

I’m sorry for wasting your time. Thank you so much for the quick fix.

@Sec-ant You’re damn right. I switched to VS Code myself a few hours ago and noticed that the problem was solved. This seems to be a problem with the WebStorm static analyzer.

I can partially reproduce this problem in a WebStorm IDE.

image

(You can see the type of path is string not string | undefined in my repro, the correct type should be string | null though)

But I do think this is an IDE bug (or mis-configuration, I don’t use WebStorm so I don’t know). Moreover, if the format type is what it is reported, then expectString(config.logger.format) should also report errors but it does not, which further suggests the IDE type hinting is somewhat problematic:

image

If this is an IDE bug, this shouldn’t affect the build process, and I can confirm no type check errors are emitted when I use npx tsc:

image

So you can still build your project without issues.

And everything works correctly under VSCode.

image

Here is my test code:

import * as v from "valibot";

export const ConfigSchema = v.object({
  logger: v.object({
    level: v.string(),
    format: v.optional(v.string(), "{icon} > {time} | {level} | {message}"),
    path: v.optional(v.nullable(v.string()), null),
  }),
});

declare function expectString(_: string): void;

declare const config: v.Output<typeof ConfigSchema>;

expectString(config.logger.format);

You are right. I am sorry. I will fix that.

Thank you very much for your work and such a quick response.