joi
joi copied to clipboard
Extracting types from a Joi schema
Support plan
- is this issue currently blocking your project? (yes/no): no
- is this issue affecting a production system? (yes/no): no
Context
- node version: >= 16.14.0
- module version: joi -> 17.6.0
- environment (e.g. node, browser, native): all
- used with (e.g. hapi application, another framework, standalone, ...): standalone
- any other relevant information: no
What problem are you trying to solve?
As we are already creating the Joi schema we don't have to write the interface for it's value type. It can be inferred from the schema itself.
// the type of the schema at this point is Joi.ObjectSchema<any>
const schema = Joi.object({
username: Joi.string().required(),
password: Joi.string().required(),
});
// we'd like to be able to extract the type from the schema
// as Joi already knows what we expect the type to be
type schema = Joi.extractType<typeof schema>;
// schema type would look like the following
// schema: {
// username: string;
// password: string
// }
Do you have a new or modified API suggestion to solve the problem?
Joi extract type plugin has solved this in the past, but hasn't kept up with the latest releases of Joi, and it does feel reliable for a long term use. Can't that logic be part of the hapi/joi library instead?
This would be a great addition, I agree!
Indeed that would simplify lots of issues on typescript projects
The problem is that many methods make this super hard to achieve.
I myself used for a long time a forked version of this fork of Joi which partially adds this: https://www.npmjs.com/package/types-joi
It is super hard to extract the type of "any.when()" or "object.or()". The issue is that it was built in a way that is hard add types to.
Personally I moved off Joi and now use Zod, which was made for this from the ground up and everything just works with typescript.
@Marsup You can "thumbs down" my comment and hand-waive it if you want but this has been lacking for more than three years. This is important for developers. And if you truly think it is important, it should have been done years ago. Joi dropped the ball hard on this. I had to migrate all my codebases because this feature keeps being pushed back with absolutely no release window.
Hapi's general attitude about types is so outdated and out of touch, it's just sad.
It's been "on the list" since June 2019 (https://github.com/hapijs/joi/issues/1557#issuecomment-501602606). Just admit defeat or at least tell us what's the problem instead of closing these issues with no response.
This is not the place for this, so…
Open only if you are interested in the previous post
joi went through several changes of leadership over the years. Although I was never too far away, I wasn't in the driver's seat when that issue was closed, and I would not like to take the blame for it. Please consider that there are humans behind this project: we also have changing priorities, life or work interferences, and we also cannot drop all the other issues for a single one, however important it may be for you. In some ways, I can understand your frustration. But the tone and attitude you demonstrated aren't consistent with the type of community we're trying to foster here. This is for the most part a free-labour based project, so please don't act like you are owed something from a project you've used and benefited from for years.
Now that the project is back under the hapi umbrella with me as main caregiver, I'm trying, as hapi did, to part ways from the BDFL model and be more inclusive of the community's changes, and I humbly think that this shows in all the issues I have answered and PRs I have merged since then. I gave the "thumbs down" because I felt your 1st comment undermined my efforts there. If I stop using a project, I don’t hang around to encourage all the others to do the same, as you've done twice: we get the message!
As for this issue, I think you among others know where I stand, after our interaction in hapijs/joi#2719: this is a desirable feature, but as you acknowledge, a super hard one that requires significant consideration around design and implementation. If you are ready to make a PR to propose a solution, by all means, do it: it would be welcome. I'm currently busy coping with several year's worth of issues and PRs, not to mention the new ones adding up, which is why I may not answer everything in a timely fashion. Right now, I’m focusing my limited energy on issues I can actually close. If you're looking for a stamp of approval, you have it!
Typescript is an important topic for both joi and hapi, and we welcome contributions, big or small, towards that effort. You may even find like-minded people to collaborate on that in slack or issues.
It might be good to know that the yup
validation library already has this feature: https://github.com/jquense/yup#typescript-integration
So, it might be good to take it as a learning/inspiration, if someone decides to work on this feature for joi
.
Haha I was checking if it is possible through joi, looks like it's not. I do know ZOD has this feature built it.
I'm brand new to Joi, which we're using because it's the default validator library supported by NestJS -- we kind of "inherited" Joi as a transitive dependency.
A lot of the Nest Configuration documentation and how-to articles seem to be perfectly happy making a separate DTO interface and Joi schema, but I'd like to describe types just once, if possible.
So: can we get a quick status update here? In early 2024, what's the state of this request? I'd be happy with a working/supported "extract" helper type, which takes a Joi.ObjectSchema
, or I'd be equally happy to write a TS interface with decorators and compile that to a runtime schema. I really just want to avoid writing everything twice.
ETA: I noticed that I can at least pass the TS interface to the Joi schema creation function like Joi.object<MyConfig>({...})
but this does not actually connect the interface property types to the property validators in the schema. For exmaple, if MyConfig has a PORT: number
, there is no compile-time type checking that the PORT
schema property is a Joi.NumberSchema
-- setting up e.g. a StringSchema
instead shows no errors.