Skip to content

Commit 7afdbec

Browse files
committed
feat: change validateAsync return type to match options
Follow-up to #2819
1 parent 88d60ff commit 7afdbec

2 files changed

Lines changed: 41 additions & 11 deletions

File tree

lib/index.d.ts

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// The following definitions have been copied (almost) as-is from:
22
// https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/hapi__joi
3-
//
3+
//
44
// Note: This file is expected to change dramatically in the next major release and have been
55
// imported here to make migrating back to the "joi" module name simpler. It include known bugs
66
// and other issues. It does not include some new features included in version 17.2.0 or newer.
@@ -107,7 +107,7 @@ declare namespace Joi {
107107
allowUnknown?: boolean;
108108
/**
109109
* when true, return artifacts alongside the value.
110-
*
110+
*
111111
* @default false
112112
*/
113113
artifacts?: boolean;
@@ -196,6 +196,12 @@ declare namespace Joi {
196196
}
197197

198198
interface AsyncValidationOptions extends ValidationOptions {
199+
/**
200+
* when true, artifacts are returned alongside the value (i.e. `{ value, artifacts }`)
201+
*
202+
* @default false
203+
*/
204+
artifacts?: boolean;
199205
/**
200206
* when true, warnings are returned alongside the value (i.e. `{ value, warning }`).
201207
*
@@ -594,7 +600,7 @@ declare namespace Joi {
594600
iterables?: boolean;
595601

596602
/**
597-
* when true, the value of the reference is used instead of its name in error messages
603+
* when true, the value of the reference is used instead of its name in error messages
598604
* and template rendering. Defaults to false.
599605
*/
600606
render?: boolean;
@@ -734,7 +740,7 @@ declare namespace Joi {
734740

735741
type NullableType<T> = undefined | null | T
736742

737-
type ObjectPropertiesSchema<T = any> =
743+
type ObjectPropertiesSchema<T = any> =
738744
T extends NullableType<string>
739745
? Joi.StringSchema
740746
: T extends NullableType<number>
@@ -753,7 +759,7 @@ declare namespace Joi {
753759

754760
type PartialSchemaMap<TSchema = any> = {
755761
[key in keyof TSchema]?: SchemaLike | SchemaLike[];
756-
}
762+
}
757763

758764
type StrictSchemaMap<TSchema = any> = {
759765
[key in keyof TSchema]-?: ObjectPropertiesSchema<TSchema[key]>
@@ -910,7 +916,7 @@ declare namespace Joi {
910916
* @param id - any value other than undefined which will be returned as-is in the result artifacts map.
911917
*/
912918
artifact(id: any): this;
913-
919+
914920
/**
915921
* By default, some Joi methods to function properly need to rely on the Joi instance they are attached to because
916922
* they use `this` internally.
@@ -1210,7 +1216,19 @@ declare namespace Joi {
12101216
/**
12111217
* Validates a value using the schema and options.
12121218
*/
1213-
validateAsync(value: any, options?: AsyncValidationOptions): Promise<TSchema>;
1219+
validateAsync<TOpts extends AsyncValidationOptions>(
1220+
value: any,
1221+
options?: TOpts
1222+
): Promise<
1223+
TOpts extends { artifacts: true } | { warnings: true }
1224+
? { value: TSchema } & (TOpts extends { artifacts: true }
1225+
? { artifacts: Map<any, string[][]> }
1226+
: {}) &
1227+
(TOpts extends { warnings: true }
1228+
? { warning: ValidationError[] }
1229+
: {})
1230+
: TSchema
1231+
>;
12141232

12151233
/**
12161234
* Same as `rule({ warn: true })`.

test/index.ts

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -984,18 +984,19 @@ schema = Joi.link(str);
984984
{ // validate tests
985985
{
986986
let value = { username: 'example', password: 'example' };
987-
const schema = Joi.object().keys({
987+
type TResult = { username: string; password: string };
988+
const schema = Joi.object<TResult>().keys({
988989
username: Joi.string().max(255).required(),
989990
password: Joi.string().pattern(/^[a-zA-Z0-9]{3,255}$/).required()
990991
});
991992
let result: Joi.ValidationResult;
992-
let asyncResult: Promise<any>;
993-
994-
value = schema.validate(value).value;
993+
let asyncResult: Promise<TResult>;
995994

996995
result = schema.validate(value);
997996
if (result.error) {
998997
throw Error('error should not be set');
998+
} else {
999+
expect.type<TResult>(result.value);
9991000
}
10001001
result = schema.validate(value, validOpts);
10011002
asyncResult = schema.validateAsync(value);
@@ -1006,6 +1007,17 @@ schema = Joi.link(str);
10061007
.then(val => { throw new Error('one error'); })
10071008
.catch(e => { });
10081009

1010+
expect.type<Promise<TResult>>(schema.validateAsync(value));
1011+
expect.type<Promise<{ value: TResult, artifacts: Map<any, string[][]> }>>(schema.validateAsync(value, { artifacts: true }));
1012+
expect.type<Promise<{ value: TResult, warning: Joi.ValidationError[] }>>(schema.validateAsync(value, { warnings: true }));
1013+
expect.type<Promise<{ value: TResult, artifacts: Map<any, string[][]>; warning: Joi.ValidationError[] }>>(schema.validateAsync(value, { artifacts: true, warnings: true }));
1014+
expect.error<Promise<{ value: TResult, warning: Joi.ValidationError[] }>>(schema.validateAsync(value, { artifacts: true }));
1015+
expect.error<Promise<{ value: TResult, artifacts: Map<any, string[][]> }>>(schema.validateAsync(value, { warnings: true }));
1016+
expect.error<Promise<TResult>>(schema.validateAsync(value, { artifacts: true, warnings: true }));
1017+
expect.type<Promise<TResult>>(schema.validateAsync(value, { artifacts: false }));
1018+
expect.type<Promise<TResult>>(schema.validateAsync(value, { warnings: false }));
1019+
expect.type<Promise<TResult>>(schema.validateAsync(value, { artifacts: false, warnings: false }));
1020+
10091021
const falsyValue = { username: 'example' };
10101022
result = schema.validate(falsyValue);
10111023
if (!result.error) {

0 commit comments

Comments
 (0)