hjkcai / typesafe-joi

A fork of joi that produces typed validation results in TypeScript
MIT License
73 stars 9 forks source link

problems with forbiddenKeys #17

Closed thomasmikava closed 5 years ago

thomasmikava commented 5 years ago

I'm very excited that optionalKeys are added. I've tested today with 2.0.2 version. As the documentation states, forbiddenKeys are added too. However, I think there is a bug.

Take this schema for example,

const userSchema = Joi.object({
    name: Joi.string().required(),
    surname: Joi.string().required(),
    age: Joi.number()
}).forbiddenKeys("name", "surname");

the type of this schema results in

ObjectSchema<Value<never, never, never, never, never>>

thus the resulting type is never, instead of { age?: number | undefined };

If I dont's pass anything to forbiddenKeys, it's still "never";

hjkcai commented 5 years ago

Fixed in 2.0.3

thomasmikava commented 5 years ago

@hjkcai, The bug is fixed, thanks. However, all values at such keys are marked as never, so I can't use it for creating another object.

For instance, when writing

const userSchema = Joi.object({
    name: Joi.string().required(),
    surname: Joi.string().required(),
    age: Joi.number()
}).forbiddenKeys("name", "surname").required();

type IUser = Joi.Literal<typeof userSchema>;

const user: IUser = {
    age: 5,
};

I get the following error:

Type '{ age: number; }' is not assignable to type '{ name: never; surname: never; } & { age?: number | undefined; }'.
  Type '{ age: number; }' is missing the following properties from type '{ name: never; surname: never; }': name, surname

Currently I handle this problem by creating custom generic type ExcludeNeverKeys, which helps me to totally remove keys that extend never.

hjkcai commented 5 years ago

Sorry for that. These keys should be optional in the resulting object. I will publish a new version to solve this.

hjkcai commented 5 years ago

@thomasmikava Try 2.0.4 please. The new version will remove all forbidden keys completely. In your case, the resulting type will be { age?: number } now.

thomasmikava commented 5 years ago

Thanks, it has been fixed