Add typings to `.extend()`
Context
- node version: 16.13.0
- module version: 17.5.0
- environment (e.g. node, browser, native): node
- used with (e.g. hapi application, another framework, standalone, ...): standalone
- any other relevant information:
What problem are you trying to solve?
Currently .extend() is typed to return any. This completely removes all typing functions (even the base package typings) whenever Joi is extended.
const Joi = require("joi").extend('@joi/date')
// Joi is now an `any` with no typings whatsoever.
Do you have a new or modified API suggestion to solve the problem?
No- I'm not good enough with typescript to figure this one out. I tried tweaking the return type from any toJoi, but this doesn't seem to work - probably something to do with Joi being a namespace, not a class.
I think Joi can benefit from using generics for the type declaration here. That way we can leave it to the engineer to describe the return type of whatever extensions they're extending.
A signature like
extend<T>(...extensions: Array<Extension | ExtensionFactory>): T;
My understanding is that Joi is not something that can be fully typed without major changes. I used a fork of Joi for a while and now I use Zod because it was made from the ground up to be Typescript compatible.
The major change is coming in the next version, in the meantime, types can likely be improved to be "good enough" in some areas.
eta on this update?
There's been a change of plans since then as you can guess from the pinned issue, so unfortunately no...
I noticed that there are some missing related typings on extension's validate
https://github.com/hapijs/joi/blob/d7afcd567bab64a79a4d38332c5b169c5f0e3bf6/lib/index.d.ts#L2001
- seems like this could be informed by the documentation: to be e.g.
validate<T>?(value: T, helpers: CustomHelpers<T>): { value: T } | { errors: ErrorReport | ErrorReport[] };
validate<T>?(value: T[], helpers: CustomHelpers<T>): { value: T[] } | { errors: ErrorReport | ErrorReport[] };
Since it will be invoked with a particular type of value (which may be an array).
- the
CustomHelperstype passed in is missing theerrorsArrayproperty which is called out loudly in the documentation for extensions
Validation helpers
- original: The original value passed untouched to validate().
- prefs: The prepared validation options.
- schema: The reference to the current schema. Useful if you need to use any of the Advanced functions.
- state: The current validation state. See Validation state.
- error: A function with signature function (code, local, localState = currentState) {} similar to $_createError() but with the current value, validation options, current state passed where: code: The error code. local: Local context used to interpolate the message. localState: The localized state.
- errorsArray: A function that creates an array that can be recognised by Joi as a valid error array. Note that using a native JS array can cause Joi to output incorrect results.
- warn: TODO
- message: TODO
https://github.com/hapijs/joi/blob/d7afcd567bab64a79a4d38332c5b169c5f0e3bf6/lib/validator.js#L200-L209
Addressing these two seem like small fixes that won't resolve the larger issue of what extend returns, but which would certainly help ease the process of implementing extensions correctly somewhat
-
anykind of makes sense if you consider that you're not forced in any way to return the same type as what was passed, it's unusual and discouraged as you'll likely run into problems if you chain other validators, but it's possible - I'd certainly take a PR for that, this pattern is both missing typings and documentation