@oscarpalmer/jhunal 0.18.0 → 0.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/constants.d.mts +7 -1
- package/dist/constants.mjs +7 -1
- package/dist/helpers.d.mts +6 -1
- package/dist/helpers.mjs +36 -10
- package/dist/index.d.mts +138 -94
- package/dist/index.mjs +128 -43
- package/dist/models/infer.model.d.mts +12 -12
- package/dist/models/misc.model.d.mts +20 -29
- package/dist/models/schema.plain.model.d.mts +4 -4
- package/dist/models/schema.typed.model.d.mts +5 -23
- package/dist/models/transform.model.d.mts +9 -13
- package/dist/models/validation.model.d.mts +49 -13
- package/dist/models/validation.model.mjs +4 -1
- package/dist/schematic.d.mts +52 -4
- package/dist/schematic.mjs +13 -4
- package/dist/validation/value.validation.d.mts +2 -2
- package/dist/validation/value.validation.mjs +78 -33
- package/package.json +1 -1
- package/src/constants.ts +16 -0
- package/src/helpers.ts +61 -15
- package/src/models/infer.model.ts +12 -12
- package/src/models/misc.model.ts +20 -29
- package/src/models/schema.plain.model.ts +4 -4
- package/src/models/schema.typed.model.ts +5 -23
- package/src/models/transform.model.ts +9 -13
- package/src/models/validation.model.ts +51 -9
- package/src/schematic.ts +79 -9
- package/src/validation/property.validation.ts +3 -4
- package/src/validation/value.validation.ts +120 -43
package/dist/constants.d.mts
CHANGED
|
@@ -2,6 +2,11 @@ import { ReportingType } from "./models/validation.model.mjs";
|
|
|
2
2
|
import { Values } from "./models/misc.model.mjs";
|
|
3
3
|
|
|
4
4
|
//#region src/constants.d.ts
|
|
5
|
+
declare const COMMA = ", ";
|
|
6
|
+
declare const CONJUNCTION_OR = " or ";
|
|
7
|
+
declare const CONJUNCTION_OR_COMMA = ", or ";
|
|
8
|
+
declare const CONJUNCTION_AND = " and ";
|
|
9
|
+
declare const CONJUNCTION_AND_COMMA = ", and ";
|
|
5
10
|
declare const MESSAGE_CONSTRUCTOR = "Expected a constructor function";
|
|
6
11
|
declare const NAME_SCHEMATIC = "Schematic";
|
|
7
12
|
declare const NAME_ERROR_SCHEMATIC = "SchematicError";
|
|
@@ -15,6 +20,7 @@ declare const VALIDATION_MESSAGE_INVALID_REQUIRED = "Expected <> for required pr
|
|
|
15
20
|
declare const VALIDATION_MESSAGE_INVALID_TYPE = "Expected <> for '<>' but received <>";
|
|
16
21
|
declare const VALIDATION_MESSAGE_INVALID_VALUE = "Value does not satisfy validator for '<>' and type '<>'";
|
|
17
22
|
declare const VALIDATION_MESSAGE_INVALID_VALUE_SUFFIX = " at index <>";
|
|
23
|
+
declare const VALIDATION_MESSAGE_UNKNOWN_KEYS = "Found keys that are not defined in the schema: <>";
|
|
18
24
|
declare const REPORTING_ALL: ReportingType;
|
|
19
25
|
declare const REPORTING_FIRST: ReportingType;
|
|
20
26
|
declare const REPORTING_NONE: ReportingType;
|
|
@@ -37,4 +43,4 @@ declare const TYPE_UNDEFINED = "undefined";
|
|
|
37
43
|
declare const VALIDATABLE_TYPES: Set<keyof Values>;
|
|
38
44
|
declare const TYPE_ALL: Set<keyof Values>;
|
|
39
45
|
//#endregion
|
|
40
|
-
export { MESSAGE_CONSTRUCTOR, NAME_ERROR_SCHEMATIC, NAME_ERROR_VALIDATION, NAME_SCHEMATIC, PROPERTY_REQUIRED, PROPERTY_SCHEMATIC, PROPERTY_TYPE, PROPERTY_VALIDATORS, REPORTING_ALL, REPORTING_FIRST, REPORTING_NONE, REPORTING_THROW, REPORTING_TYPES, SCHEMATIC_MESSAGE_SCHEMA_INVALID_EMPTY, SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_DISALLOWED, SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_NULLABLE, SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_REQUIRED, SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_TYPE, SCHEMATIC_MESSAGE_SCHEMA_INVALID_TYPE, SCHEMATIC_MESSAGE_VALIDATOR_INVALID_KEY, SCHEMATIC_MESSAGE_VALIDATOR_INVALID_TYPE, SCHEMATIC_MESSAGE_VALIDATOR_INVALID_VALUE, TEMPLATE_PATTERN, TYPE_ALL, TYPE_ARRAY, TYPE_NULL, TYPE_OBJECT, TYPE_UNDEFINED, VALIDATABLE_TYPES, VALIDATION_MESSAGE_INVALID_INPUT, VALIDATION_MESSAGE_INVALID_REQUIRED, VALIDATION_MESSAGE_INVALID_TYPE, VALIDATION_MESSAGE_INVALID_VALUE, VALIDATION_MESSAGE_INVALID_VALUE_SUFFIX };
|
|
46
|
+
export { COMMA, CONJUNCTION_AND, CONJUNCTION_AND_COMMA, CONJUNCTION_OR, CONJUNCTION_OR_COMMA, MESSAGE_CONSTRUCTOR, NAME_ERROR_SCHEMATIC, NAME_ERROR_VALIDATION, NAME_SCHEMATIC, PROPERTY_REQUIRED, PROPERTY_SCHEMATIC, PROPERTY_TYPE, PROPERTY_VALIDATORS, REPORTING_ALL, REPORTING_FIRST, REPORTING_NONE, REPORTING_THROW, REPORTING_TYPES, SCHEMATIC_MESSAGE_SCHEMA_INVALID_EMPTY, SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_DISALLOWED, SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_NULLABLE, SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_REQUIRED, SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_TYPE, SCHEMATIC_MESSAGE_SCHEMA_INVALID_TYPE, SCHEMATIC_MESSAGE_VALIDATOR_INVALID_KEY, SCHEMATIC_MESSAGE_VALIDATOR_INVALID_TYPE, SCHEMATIC_MESSAGE_VALIDATOR_INVALID_VALUE, TEMPLATE_PATTERN, TYPE_ALL, TYPE_ARRAY, TYPE_NULL, TYPE_OBJECT, TYPE_UNDEFINED, VALIDATABLE_TYPES, VALIDATION_MESSAGE_INVALID_INPUT, VALIDATION_MESSAGE_INVALID_REQUIRED, VALIDATION_MESSAGE_INVALID_TYPE, VALIDATION_MESSAGE_INVALID_VALUE, VALIDATION_MESSAGE_INVALID_VALUE_SUFFIX, VALIDATION_MESSAGE_UNKNOWN_KEYS };
|
package/dist/constants.mjs
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
//#region src/constants.ts
|
|
2
|
+
const COMMA = ", ";
|
|
3
|
+
const CONJUNCTION_OR = " or ";
|
|
4
|
+
const CONJUNCTION_OR_COMMA = ", or ";
|
|
5
|
+
const CONJUNCTION_AND = " and ";
|
|
6
|
+
const CONJUNCTION_AND_COMMA = ", and ";
|
|
2
7
|
const MESSAGE_CONSTRUCTOR = "Expected a constructor function";
|
|
3
8
|
const NAME_SCHEMATIC = "Schematic";
|
|
4
9
|
const NAME_ERROR_SCHEMATIC = "SchematicError";
|
|
@@ -12,6 +17,7 @@ const VALIDATION_MESSAGE_INVALID_REQUIRED = "Expected <> for required property '
|
|
|
12
17
|
const VALIDATION_MESSAGE_INVALID_TYPE = "Expected <> for '<>' but received <>";
|
|
13
18
|
const VALIDATION_MESSAGE_INVALID_VALUE = "Value does not satisfy validator for '<>' and type '<>'";
|
|
14
19
|
const VALIDATION_MESSAGE_INVALID_VALUE_SUFFIX = " at index <>";
|
|
20
|
+
const VALIDATION_MESSAGE_UNKNOWN_KEYS = "Found keys that are not defined in the schema: <>";
|
|
15
21
|
const REPORTING_ALL = "all";
|
|
16
22
|
const REPORTING_FIRST = "first";
|
|
17
23
|
const REPORTING_NONE = "none";
|
|
@@ -53,4 +59,4 @@ const TYPE_ALL = new Set([
|
|
|
53
59
|
TYPE_UNDEFINED
|
|
54
60
|
]);
|
|
55
61
|
//#endregion
|
|
56
|
-
export { MESSAGE_CONSTRUCTOR, NAME_ERROR_SCHEMATIC, NAME_ERROR_VALIDATION, NAME_SCHEMATIC, PROPERTY_REQUIRED, PROPERTY_SCHEMATIC, PROPERTY_TYPE, PROPERTY_VALIDATORS, REPORTING_ALL, REPORTING_FIRST, REPORTING_NONE, REPORTING_THROW, REPORTING_TYPES, SCHEMATIC_MESSAGE_SCHEMA_INVALID_EMPTY, SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_DISALLOWED, SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_NULLABLE, SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_REQUIRED, SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_TYPE, SCHEMATIC_MESSAGE_SCHEMA_INVALID_TYPE, SCHEMATIC_MESSAGE_VALIDATOR_INVALID_KEY, SCHEMATIC_MESSAGE_VALIDATOR_INVALID_TYPE, SCHEMATIC_MESSAGE_VALIDATOR_INVALID_VALUE, TEMPLATE_PATTERN, TYPE_ALL, TYPE_ARRAY, TYPE_NULL, TYPE_OBJECT, TYPE_UNDEFINED, VALIDATABLE_TYPES, VALIDATION_MESSAGE_INVALID_INPUT, VALIDATION_MESSAGE_INVALID_REQUIRED, VALIDATION_MESSAGE_INVALID_TYPE, VALIDATION_MESSAGE_INVALID_VALUE, VALIDATION_MESSAGE_INVALID_VALUE_SUFFIX };
|
|
62
|
+
export { COMMA, CONJUNCTION_AND, CONJUNCTION_AND_COMMA, CONJUNCTION_OR, CONJUNCTION_OR_COMMA, MESSAGE_CONSTRUCTOR, NAME_ERROR_SCHEMATIC, NAME_ERROR_VALIDATION, NAME_SCHEMATIC, PROPERTY_REQUIRED, PROPERTY_SCHEMATIC, PROPERTY_TYPE, PROPERTY_VALIDATORS, REPORTING_ALL, REPORTING_FIRST, REPORTING_NONE, REPORTING_THROW, REPORTING_TYPES, SCHEMATIC_MESSAGE_SCHEMA_INVALID_EMPTY, SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_DISALLOWED, SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_NULLABLE, SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_REQUIRED, SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_TYPE, SCHEMATIC_MESSAGE_SCHEMA_INVALID_TYPE, SCHEMATIC_MESSAGE_VALIDATOR_INVALID_KEY, SCHEMATIC_MESSAGE_VALIDATOR_INVALID_TYPE, SCHEMATIC_MESSAGE_VALIDATOR_INVALID_VALUE, TEMPLATE_PATTERN, TYPE_ALL, TYPE_ARRAY, TYPE_NULL, TYPE_OBJECT, TYPE_UNDEFINED, VALIDATABLE_TYPES, VALIDATION_MESSAGE_INVALID_INPUT, VALIDATION_MESSAGE_INVALID_REQUIRED, VALIDATION_MESSAGE_INVALID_TYPE, VALIDATION_MESSAGE_INVALID_VALUE, VALIDATION_MESSAGE_INVALID_VALUE_SUFFIX, VALIDATION_MESSAGE_UNKNOWN_KEYS };
|
package/dist/helpers.d.mts
CHANGED
|
@@ -8,7 +8,12 @@ declare function getInvalidInputMessage(actual: unknown): string;
|
|
|
8
8
|
declare function getInvalidMissingMessage(property: ValidatedProperty): string;
|
|
9
9
|
declare function getInvalidTypeMessage(property: ValidatedProperty, actual: unknown): string;
|
|
10
10
|
declare function getInvalidValidatorMessage(property: ValidatedProperty, type: ValueName, index: number, length: number): string;
|
|
11
|
+
declare function getOptions(input: unknown): {
|
|
12
|
+
reporting: ReportingInformation;
|
|
13
|
+
strict: boolean;
|
|
14
|
+
};
|
|
11
15
|
declare function getReporting(value: unknown): ReportingInformation;
|
|
16
|
+
declare function getUnknownKeysMessage(keys: string[]): string;
|
|
12
17
|
/**
|
|
13
18
|
* Creates a validator function for a given constructor
|
|
14
19
|
* @param constructor - Constructor to check against
|
|
@@ -23,4 +28,4 @@ declare function instanceOf<Instance>(constructor: Constructor<Instance>): (valu
|
|
|
23
28
|
*/
|
|
24
29
|
declare function isSchematic(value: unknown): value is Schematic<never>;
|
|
25
30
|
//#endregion
|
|
26
|
-
export { getInvalidInputMessage, getInvalidMissingMessage, getInvalidTypeMessage, getInvalidValidatorMessage, getReporting, instanceOf, isSchematic };
|
|
31
|
+
export { getInvalidInputMessage, getInvalidMissingMessage, getInvalidTypeMessage, getInvalidValidatorMessage, getOptions, getReporting, getUnknownKeysMessage, instanceOf, isSchematic };
|
package/dist/helpers.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { MESSAGE_CONSTRUCTOR, NAME_SCHEMATIC, REPORTING_FIRST, REPORTING_NONE, REPORTING_THROW, REPORTING_TYPES, TYPE_ARRAY, TYPE_NULL, TYPE_OBJECT, TYPE_UNDEFINED, VALIDATION_MESSAGE_INVALID_INPUT, VALIDATION_MESSAGE_INVALID_REQUIRED, VALIDATION_MESSAGE_INVALID_TYPE, VALIDATION_MESSAGE_INVALID_VALUE, VALIDATION_MESSAGE_INVALID_VALUE_SUFFIX } from "./constants.mjs";
|
|
1
|
+
import { CONJUNCTION_AND, CONJUNCTION_AND_COMMA, CONJUNCTION_OR, CONJUNCTION_OR_COMMA, MESSAGE_CONSTRUCTOR, NAME_SCHEMATIC, REPORTING_FIRST, REPORTING_NONE, REPORTING_THROW, REPORTING_TYPES, TYPE_ARRAY, TYPE_NULL, TYPE_OBJECT, TYPE_UNDEFINED, VALIDATION_MESSAGE_INVALID_INPUT, VALIDATION_MESSAGE_INVALID_REQUIRED, VALIDATION_MESSAGE_INVALID_TYPE, VALIDATION_MESSAGE_INVALID_VALUE, VALIDATION_MESSAGE_INVALID_VALUE_SUFFIX, VALIDATION_MESSAGE_UNKNOWN_KEYS } from "./constants.mjs";
|
|
2
2
|
import { isConstructor, isPlainObject } from "@oscarpalmer/atoms/is";
|
|
3
3
|
//#region src/helpers.ts
|
|
4
4
|
function getInvalidInputMessage(actual) {
|
|
@@ -21,6 +21,21 @@ function getInvalidValidatorMessage(property, type, index, length) {
|
|
|
21
21
|
if (length > 1) message += VALIDATION_MESSAGE_INVALID_VALUE_SUFFIX.replace("<>", String(index));
|
|
22
22
|
return message;
|
|
23
23
|
}
|
|
24
|
+
function getOptions(input) {
|
|
25
|
+
if (typeof input === "boolean") return {
|
|
26
|
+
reporting: getReporting(REPORTING_NONE),
|
|
27
|
+
strict: input
|
|
28
|
+
};
|
|
29
|
+
if (REPORTING_TYPES.has(input)) return {
|
|
30
|
+
reporting: getReporting(input),
|
|
31
|
+
strict: false
|
|
32
|
+
};
|
|
33
|
+
const options = isPlainObject(input) ? input : {};
|
|
34
|
+
return {
|
|
35
|
+
reporting: getReporting(options.errors),
|
|
36
|
+
strict: typeof options.strict === "boolean" ? options.strict : false
|
|
37
|
+
};
|
|
38
|
+
}
|
|
24
39
|
function getPropertyType(original) {
|
|
25
40
|
if (typeof original === "function") return "a validated value";
|
|
26
41
|
if (Array.isArray(original)) return `'${TYPE_OBJECT}'`;
|
|
@@ -30,12 +45,16 @@ function getPropertyType(original) {
|
|
|
30
45
|
function getReporting(value) {
|
|
31
46
|
const type = REPORTING_TYPES.has(value) ? value : REPORTING_NONE;
|
|
32
47
|
return {
|
|
48
|
+
type,
|
|
33
49
|
["all"]: type === "all",
|
|
34
50
|
[REPORTING_FIRST]: type === REPORTING_FIRST,
|
|
35
51
|
[REPORTING_NONE]: type === REPORTING_NONE,
|
|
36
52
|
[REPORTING_THROW]: type === REPORTING_THROW
|
|
37
53
|
};
|
|
38
54
|
}
|
|
55
|
+
function getUnknownKeysMessage(keys) {
|
|
56
|
+
return VALIDATION_MESSAGE_UNKNOWN_KEYS.replace("<>", renderKeys(keys));
|
|
57
|
+
}
|
|
39
58
|
function getValueType(value) {
|
|
40
59
|
const valueType = typeof value;
|
|
41
60
|
switch (true) {
|
|
@@ -68,6 +87,20 @@ function instanceOf(constructor) {
|
|
|
68
87
|
function isSchematic(value) {
|
|
69
88
|
return typeof value === "object" && value !== null && "$schematic" in value && value["$schematic"] === true;
|
|
70
89
|
}
|
|
90
|
+
function renderKeys(keys) {
|
|
91
|
+
return renderParts(keys.map((key) => `'${key}'`), CONJUNCTION_AND, CONJUNCTION_AND_COMMA);
|
|
92
|
+
}
|
|
93
|
+
function renderParts(parts, delimiterShort, delimiterLong) {
|
|
94
|
+
const { length } = parts;
|
|
95
|
+
if (length === 1) return parts[0];
|
|
96
|
+
let rendered = "";
|
|
97
|
+
for (let index = 0; index < length; index += 1) {
|
|
98
|
+
rendered += parts[index];
|
|
99
|
+
if (index < length - 2) rendered += ", ";
|
|
100
|
+
else if (index === length - 2) rendered += parts.length > 2 ? delimiterLong : delimiterShort;
|
|
101
|
+
}
|
|
102
|
+
return rendered;
|
|
103
|
+
}
|
|
71
104
|
function renderTypes(types) {
|
|
72
105
|
const unique = /* @__PURE__ */ new Set();
|
|
73
106
|
const parts = [];
|
|
@@ -77,14 +110,7 @@ function renderTypes(types) {
|
|
|
77
110
|
unique.add(rendered);
|
|
78
111
|
parts.push(rendered);
|
|
79
112
|
}
|
|
80
|
-
|
|
81
|
-
let rendered = "";
|
|
82
|
-
for (let index = 0; index < length; index += 1) {
|
|
83
|
-
rendered += parts[index];
|
|
84
|
-
if (index < length - 2) rendered += ", ";
|
|
85
|
-
else if (index === length - 2) rendered += parts.length > 2 ? ", or " : " or ";
|
|
86
|
-
}
|
|
87
|
-
return rendered;
|
|
113
|
+
return renderParts(parts, CONJUNCTION_OR, CONJUNCTION_OR_COMMA);
|
|
88
114
|
}
|
|
89
115
|
//#endregion
|
|
90
|
-
export { getInvalidInputMessage, getInvalidMissingMessage, getInvalidTypeMessage, getInvalidValidatorMessage, getReporting, instanceOf, isSchematic };
|
|
116
|
+
export { getInvalidInputMessage, getInvalidMissingMessage, getInvalidTypeMessage, getInvalidValidatorMessage, getOptions, getReporting, getUnknownKeysMessage, instanceOf, isSchematic };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { Constructor, GenericCallback, PlainObject, Simplify } from "@oscarpalmer/atoms/models";
|
|
2
|
+
import { Result } from "@oscarpalmer/atoms/result/models";
|
|
2
3
|
|
|
3
4
|
//#region src/models/infer.model.d.ts
|
|
4
5
|
/**
|
|
5
6
|
* Infers the TypeScript type from a {@link Schema} definition
|
|
6
7
|
*
|
|
7
|
-
* @template Model
|
|
8
|
+
* @template Model Schema to infer types from
|
|
8
9
|
*
|
|
9
10
|
* @example
|
|
10
11
|
* ```ts
|
|
@@ -26,37 +27,37 @@ type Infer<Model extends Schema> = Simplify<{ [Key in InferRequiredKeys<Model>]:
|
|
|
26
27
|
*/
|
|
27
28
|
type InferOptionalKeys<Model extends Schema> = keyof { [Key in keyof Model as IsOptionalProperty<Model[Key]> extends true ? Key : never]: never };
|
|
28
29
|
/**
|
|
29
|
-
* Infers the TypeScript type
|
|
30
|
+
* Infers the TypeScript type from a {@link SchemaProperty}'s `$type` field
|
|
30
31
|
*
|
|
31
|
-
* @template Value
|
|
32
|
+
* @template Value `$type` value _(single or array)_
|
|
32
33
|
*/
|
|
33
34
|
type InferPropertyType<Value> = Value extends (infer Item)[] ? InferPropertyValue<Item> : InferPropertyValue<Value>;
|
|
34
35
|
/**
|
|
35
|
-
* Maps a single type definition to its TypeScript equivalent
|
|
36
|
+
* Maps a single `$type` definition to its TypeScript equivalent
|
|
36
37
|
*
|
|
37
|
-
* Resolves, in order: {@link Constructor} instances, {@link Schematic} models, {@link ValueName} strings, and nested {@link
|
|
38
|
+
* Resolves, in order: {@link Constructor} instances, {@link Schematic} models, {@link ValueName} strings, and nested {@link PlainSchema} objects
|
|
38
39
|
*
|
|
39
|
-
* @template Value
|
|
40
|
+
* @template Value single type definition
|
|
40
41
|
*/
|
|
41
42
|
type InferPropertyValue<Value> = Value extends Constructor<infer Instance> ? Instance : Value extends Schematic<infer Model> ? Model : Value extends ValueName ? Values[Value & ValueName] : Value extends Schema ? Infer<Value> : never;
|
|
42
43
|
/**
|
|
43
44
|
* Extracts keys from a {@link Schema} whose entries are required _(i.e., `$required` is not `false`)_
|
|
44
45
|
*
|
|
45
|
-
* @template Model
|
|
46
|
+
* @template Model Schema to extract required keys from
|
|
46
47
|
*/
|
|
47
48
|
type InferRequiredKeys<Model extends Schema> = keyof { [Key in keyof Model as IsOptionalProperty<Model[Key]> extends true ? never : Key]: never };
|
|
48
49
|
/**
|
|
49
|
-
* Infers the type
|
|
50
|
+
* Infers the TypeScript type from a top-level {@link Schema} entry
|
|
50
51
|
*
|
|
51
|
-
* @template Value
|
|
52
|
+
* @template Value Schema entry value _(single or array)_
|
|
52
53
|
*/
|
|
53
54
|
type InferSchemaEntry<Value> = Value extends (infer Item)[] ? InferSchemaEntryValue<Item> : InferSchemaEntryValue<Value>;
|
|
54
55
|
/**
|
|
55
|
-
*
|
|
56
|
+
* Maps a single top-level schema entry to its TypeScript type
|
|
56
57
|
*
|
|
57
|
-
*
|
|
58
|
+
* Resolves, in order: {@link Constructor} instances, {@link Schematic} models, {@link SchemaProperty} objects, {@link PlainSchema} objects, and {@link ValueName} strings
|
|
58
59
|
*
|
|
59
|
-
* @template Value
|
|
60
|
+
* @template Value single schema entry
|
|
60
61
|
*/
|
|
61
62
|
type InferSchemaEntryValue<Value> = Value extends Constructor<infer Instance> ? Instance : Value extends Schematic<infer Model> ? Model : Value extends SchemaProperty ? InferPropertyType<Value['$type']> : Value extends PlainSchema ? Infer<Value & Schema> : Value extends ValueName ? Values[Value & ValueName] : Value extends Schema ? Infer<Value> : never;
|
|
62
63
|
//#endregion
|
|
@@ -64,37 +65,33 @@ type InferSchemaEntryValue<Value> = Value extends Constructor<infer Instance> ?
|
|
|
64
65
|
/**
|
|
65
66
|
* Maps each element of a tuple through {@link ToValueType}
|
|
66
67
|
*
|
|
67
|
-
* @template Value
|
|
68
|
+
* @template Value Tuple of types to map
|
|
68
69
|
*/
|
|
69
70
|
type MapToValueTypes<Value extends unknown[]> = Value extends [infer Head, ...infer Tail] ? [ToValueType<Head>, ...MapToValueTypes<Tail>] : [];
|
|
70
71
|
/**
|
|
71
72
|
* Maps each element of a tuple through {@link ToSchemaPropertyTypeEach}
|
|
72
73
|
*
|
|
73
|
-
* @template Value
|
|
74
|
+
* @template Value Tuple of types to map
|
|
74
75
|
*/
|
|
75
76
|
type MapToSchemaPropertyTypes<Value extends unknown[]> = Value extends [infer Head, ...infer Tail] ? [ToSchemaPropertyTypeEach<Head>, ...MapToSchemaPropertyTypes<Tail>] : [];
|
|
76
77
|
/**
|
|
77
|
-
* Converts a type
|
|
78
|
+
* Converts a TypeScript type to its {@link SchemaPropertyType} representation, suitable for use in a typed schema
|
|
78
79
|
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
* @template Value - type to convert
|
|
80
|
+
* @template Value Type to convert
|
|
82
81
|
*/
|
|
83
82
|
type ToSchemaPropertyType<Value> = UnwrapSingle<DeduplicateTuple<MapToSchemaPropertyTypes<UnionToTuple<Value>>>>;
|
|
84
83
|
/**
|
|
85
84
|
* Converts a single type to its schema property equivalent
|
|
86
85
|
*
|
|
87
|
-
*
|
|
86
|
+
* Plain objects become {@link TypedSchema}; primitives go through {@link ToValueType}
|
|
88
87
|
*
|
|
89
|
-
* @template Value
|
|
88
|
+
* @template Value Type to convert
|
|
90
89
|
*/
|
|
91
90
|
type ToSchemaPropertyTypeEach<Value> = Value extends PlainObject ? TypedSchema<Value> : ToValueType<Value>;
|
|
92
91
|
/**
|
|
93
|
-
* Converts a type
|
|
94
|
-
*
|
|
95
|
-
* Deduplicates and unwraps single-element tuples via {@link UnwrapSingle}
|
|
92
|
+
* Converts a TypeScript type to its {@link ValueName} representation, suitable for use as a top-level schema entry
|
|
96
93
|
*
|
|
97
|
-
* @template Value
|
|
94
|
+
* @template Value Type to convert
|
|
98
95
|
*/
|
|
99
96
|
type ToSchemaType<Value> = UnwrapSingle<DeduplicateTuple<MapToValueTypes<UnionToTuple<Value>>>>;
|
|
100
97
|
/**
|
|
@@ -102,7 +99,7 @@ type ToSchemaType<Value> = UnwrapSingle<DeduplicateTuple<MapToValueTypes<UnionTo
|
|
|
102
99
|
*
|
|
103
100
|
* Resolves {@link Schematic} types as-is, then performs a reverse-lookup against {@link Values} _(excluding `'object'`)_ to find a matching key. If no match is found, `object` types resolve to `'object'` or a type-guard function, and all other unrecognised types resolve to a type-guard function
|
|
104
101
|
*
|
|
105
|
-
* @template Value
|
|
102
|
+
* @template Value Type to map
|
|
106
103
|
*
|
|
107
104
|
* @example
|
|
108
105
|
* ```ts
|
|
@@ -117,7 +114,7 @@ type ToValueType<Value> = Value extends Schematic<any> ? Value : { [Key in keyof
|
|
|
117
114
|
/**
|
|
118
115
|
* A typed optional property definition generated by {@link TypedSchema} for optional keys, with `$required` set to `false` and excludes `undefined` from the type
|
|
119
116
|
*
|
|
120
|
-
* @template Value
|
|
117
|
+
* @template Value Property's type _(including `undefined`)_
|
|
121
118
|
*
|
|
122
119
|
* @example
|
|
123
120
|
* ```ts
|
|
@@ -127,23 +124,14 @@ type ToValueType<Value> = Value extends Schematic<any> ? Value : { [Key in keyof
|
|
|
127
124
|
* ```
|
|
128
125
|
*/
|
|
129
126
|
type TypedPropertyOptional<Value> = {
|
|
130
|
-
/**
|
|
131
|
-
* The property is not required
|
|
132
|
-
*/
|
|
133
127
|
$required: false;
|
|
134
|
-
/**
|
|
135
|
-
* The type(s) of the property
|
|
136
|
-
*/
|
|
137
128
|
$type: ToSchemaPropertyType<Exclude<Value, undefined>>;
|
|
138
|
-
/**
|
|
139
|
-
* Custom validators for the property and its types
|
|
140
|
-
*/
|
|
141
129
|
$validators?: PropertyValidators<ToSchemaPropertyType<Exclude<Value, undefined>>>;
|
|
142
130
|
};
|
|
143
131
|
/**
|
|
144
132
|
* A typed required property definition generated by {@link TypedSchema} for required keys, with `$required` defaulting to `true`
|
|
145
133
|
*
|
|
146
|
-
* @template Value
|
|
134
|
+
* @template Value Property's type
|
|
147
135
|
*
|
|
148
136
|
* @example
|
|
149
137
|
* ```ts
|
|
@@ -153,17 +141,8 @@ type TypedPropertyOptional<Value> = {
|
|
|
153
141
|
* ```
|
|
154
142
|
*/
|
|
155
143
|
type TypedPropertyRequired<Value> = {
|
|
156
|
-
/**
|
|
157
|
-
* The property is required _(defaults to `true`)_
|
|
158
|
-
*/
|
|
159
144
|
$required?: true;
|
|
160
|
-
/**
|
|
161
|
-
* The type(s) of the property
|
|
162
|
-
*/
|
|
163
145
|
$type: ToSchemaPropertyType<Value>;
|
|
164
|
-
/**
|
|
165
|
-
* Custom validators for the property and its types
|
|
166
|
-
*/
|
|
167
146
|
$validators?: PropertyValidators<ToSchemaPropertyType<Value>>;
|
|
168
147
|
};
|
|
169
148
|
/**
|
|
@@ -171,7 +150,7 @@ type TypedPropertyRequired<Value> = {
|
|
|
171
150
|
*
|
|
172
151
|
* Required keys map to {@link ToSchemaType} or {@link TypedPropertyRequired}; plain object values may also use {@link Schematic}. Optional keys map to {@link TypedPropertyOptional} or, for plain objects, {@link TypedSchemaOptional}
|
|
173
152
|
*
|
|
174
|
-
* @template Model
|
|
153
|
+
* @template Model Object type to generate a schema for
|
|
175
154
|
*
|
|
176
155
|
* @example
|
|
177
156
|
* ```ts
|
|
@@ -188,7 +167,7 @@ type TypedSchema<Model extends PlainObject> = Simplify<{ [Key in RequiredKeys<Mo
|
|
|
188
167
|
/**
|
|
189
168
|
* A {@link TypedSchema} variant for optional nested objects, with `$required` fixed to `false`
|
|
190
169
|
*
|
|
191
|
-
* @template Model
|
|
170
|
+
* @template Model Nested object type
|
|
192
171
|
*/
|
|
193
172
|
type TypedSchemaOptional<Model extends PlainObject> = {
|
|
194
173
|
$required: false;
|
|
@@ -196,7 +175,7 @@ type TypedSchemaOptional<Model extends PlainObject> = {
|
|
|
196
175
|
/**
|
|
197
176
|
* A {@link TypedSchema} variant for required nested objects, with `$required` defaulting to `true`
|
|
198
177
|
*
|
|
199
|
-
* @template Model
|
|
178
|
+
* @template Model Nested object type
|
|
200
179
|
*/
|
|
201
180
|
type TypedSchemaRequired<Model extends PlainObject> = {
|
|
202
181
|
$required?: true;
|
|
@@ -204,7 +183,16 @@ type TypedSchemaRequired<Model extends PlainObject> = {
|
|
|
204
183
|
//#endregion
|
|
205
184
|
//#region src/models/validation.model.d.ts
|
|
206
185
|
/**
|
|
207
|
-
*
|
|
186
|
+
* Controls how validation failures are reported
|
|
187
|
+
*
|
|
188
|
+
* - `'none'` — returns a boolean _(default)_
|
|
189
|
+
* - `'first'` — returns the first failure as a `Result`
|
|
190
|
+
* - `'all'` — returns all failures as a `Result` _(from same level)_
|
|
191
|
+
* - `'throw'` — throws a {@link ValidationError} on failure
|
|
192
|
+
*/
|
|
193
|
+
type ReportingType = 'all' | 'first' | 'none' | 'throw';
|
|
194
|
+
/**
|
|
195
|
+
* Thrown when a schema definition is invalid
|
|
208
196
|
*/
|
|
209
197
|
declare class SchematicError extends Error {
|
|
210
198
|
constructor(message: string);
|
|
@@ -241,16 +229,12 @@ type ValidatedProperty = {
|
|
|
241
229
|
validators: ValidatedPropertyValidators;
|
|
242
230
|
};
|
|
243
231
|
/**
|
|
244
|
-
*
|
|
232
|
+
* The full and short forms of a property's key path
|
|
233
|
+
*
|
|
234
|
+
* For a nested property `address.street`: `full` is `'address.street'`, `short` is `'street'`
|
|
245
235
|
*/
|
|
246
236
|
type ValidatedPropertyKey = {
|
|
247
|
-
/**
|
|
248
|
-
* Full property key, including parent keys for nested properties _(e.g., `address.street`)_
|
|
249
|
-
*/
|
|
250
237
|
full: string;
|
|
251
|
-
/**
|
|
252
|
-
* The last segment of the property key _(e.g., `street` for `address.street`)_
|
|
253
|
-
*/
|
|
254
238
|
short: string;
|
|
255
239
|
};
|
|
256
240
|
/**
|
|
@@ -265,16 +249,39 @@ type ValidatedPropertyType = GenericCallback | ValidatedProperty[] | Schematic<u
|
|
|
265
249
|
* Each key holds an array of validator functions that receive an `unknown` value and return a `boolean`
|
|
266
250
|
*/
|
|
267
251
|
type ValidatedPropertyValidators = { [Key in ValueName]?: Array<(value: unknown) => boolean> };
|
|
252
|
+
/**
|
|
253
|
+
* Thrown in `'throw'` mode when one or more properties fail validation; `information` holds all failures
|
|
254
|
+
*/
|
|
268
255
|
declare class ValidationError extends Error {
|
|
269
256
|
readonly information: ValidationInformation[];
|
|
270
257
|
constructor(information: ValidationInformation[]);
|
|
271
258
|
}
|
|
259
|
+
/**
|
|
260
|
+
* Describes a single validation failure
|
|
261
|
+
*/
|
|
272
262
|
type ValidationInformation = {
|
|
273
|
-
key: ValidationInformationKey;
|
|
274
|
-
message: string;
|
|
275
|
-
validator?: GenericCallback;
|
|
263
|
+
/** The key path of the property that failed */key: ValidationInformationKey; /** Human-readable description of the failure */
|
|
264
|
+
message: string; /** The validator function that failed, if the failure was from a `$validators` entry */
|
|
265
|
+
validator?: GenericCallback; /** The value that was provided */
|
|
266
|
+
value: unknown;
|
|
276
267
|
};
|
|
268
|
+
/**
|
|
269
|
+
* Same shape as {@link ValidatedPropertyKey}; the key path of a failed property
|
|
270
|
+
*/
|
|
277
271
|
type ValidationInformationKey = ValidatedPropertyKey;
|
|
272
|
+
/**
|
|
273
|
+
* Options for validation
|
|
274
|
+
*/
|
|
275
|
+
type ValidationOptions<Errors extends ReportingType> = {
|
|
276
|
+
/**
|
|
277
|
+
* How should validation failures be reported; see {@link ReportingType} _(defaults to `'none'`)_
|
|
278
|
+
*/
|
|
279
|
+
errors?: Errors;
|
|
280
|
+
/**
|
|
281
|
+
* Validate if unknown keys are present in the object? _(defaults to `false`)_
|
|
282
|
+
*/
|
|
283
|
+
strict?: boolean;
|
|
284
|
+
};
|
|
278
285
|
//#endregion
|
|
279
286
|
//#region src/schematic.d.ts
|
|
280
287
|
/**
|
|
@@ -289,18 +296,64 @@ declare class Schematic<Model> {
|
|
|
289
296
|
*
|
|
290
297
|
* Will assert that the values matches the schema and throw an error if it does not. The error will contain all validation information for the first property that fails validation.
|
|
291
298
|
* @param value Value to validate
|
|
292
|
-
* @param
|
|
299
|
+
* @param options Validation options
|
|
300
|
+
* @returns `true` if the value matches the schema, otherwise throws an error
|
|
301
|
+
*/
|
|
302
|
+
is(value: unknown, options: ValidationOptions<'throw'>): asserts value is Model;
|
|
303
|
+
/**
|
|
304
|
+
* Does the value match the schema?
|
|
305
|
+
*
|
|
306
|
+
* Will assert that the values matches the schema and throw an error if it does not. The error will contain all validation information for the first property that fails validation.
|
|
307
|
+
* @param value Value to validate
|
|
308
|
+
* @param errors Reporting type
|
|
293
309
|
* @returns `true` if the value matches the schema, otherwise throws an error
|
|
294
310
|
*/
|
|
295
311
|
is(value: unknown, errors: 'throw'): asserts value is Model;
|
|
312
|
+
/**
|
|
313
|
+
* Does the value match the schema?
|
|
314
|
+
*
|
|
315
|
+
* Will validate that the value matches the schema and return a result of `true` or all validation information for validation failures from the same depth in the object.
|
|
316
|
+
* @param value Value to validate
|
|
317
|
+
* @param options Validation options
|
|
318
|
+
* @returns `true` if the value matches the schema, otherwise `false`
|
|
319
|
+
*/
|
|
320
|
+
is(value: unknown, options: ValidationOptions<'all'>): Result<true, ValidationInformation[]>;
|
|
321
|
+
/**
|
|
322
|
+
* Does the value match the schema?
|
|
323
|
+
*
|
|
324
|
+
* Will validate that the value matches the schema and return a result of `true` or all validation information for validation failures from the same depth in the object.
|
|
325
|
+
* @param value Value to validate
|
|
326
|
+
* @param errors Reporting type
|
|
327
|
+
* @returns `true` if the value matches the schema, otherwise `false`
|
|
328
|
+
*/
|
|
329
|
+
is(value: unknown, errors: 'all'): Result<true, ValidationInformation[]>;
|
|
330
|
+
/**
|
|
331
|
+
* Does the value match the schema?
|
|
332
|
+
*
|
|
333
|
+
* Will validate that the value matches the schema and return a result of `true` or all validation information for the failing property.
|
|
334
|
+
* @param value Value to validate
|
|
335
|
+
* @param options Validation options
|
|
336
|
+
* @returns `true` if the value matches the schema, otherwise `false`
|
|
337
|
+
*/
|
|
338
|
+
is(value: unknown, options: ValidationOptions<'first'>): Result<true, ValidationInformation>;
|
|
339
|
+
/**
|
|
340
|
+
* Does the value match the schema?
|
|
341
|
+
*
|
|
342
|
+
* Will validate that the value matches the schema and return a result of `true` or all validation information for the failing property.
|
|
343
|
+
* @param value Value to validate
|
|
344
|
+
* @param errors Reporting type
|
|
345
|
+
* @returns `true` if the value matches the schema, otherwise `false`
|
|
346
|
+
*/
|
|
347
|
+
is(value: unknown, errors: 'first'): Result<true, ValidationInformation>;
|
|
296
348
|
/**
|
|
297
349
|
* Does the value match the schema?
|
|
298
350
|
*
|
|
299
351
|
* Will validate that the value matches the schema and return `true` or `false`, without any validation information for validation failures.
|
|
300
352
|
* @param value Value to validate
|
|
353
|
+
* @param strict Validate if unknown keys are present in the object? _(defaults to `false`)_
|
|
301
354
|
* @returns `true` if the value matches the schema, otherwise `false`
|
|
302
355
|
*/
|
|
303
|
-
is(value: unknown): value is Model;
|
|
356
|
+
is(value: unknown, strict?: true): value is Model;
|
|
304
357
|
}
|
|
305
358
|
/**
|
|
306
359
|
* Create a schematic from a schema
|
|
@@ -321,7 +374,7 @@ declare function schematic<Model extends PlainObject>(schema: TypedSchema<Model>
|
|
|
321
374
|
//#endregion
|
|
322
375
|
//#region src/models/schema.plain.model.d.ts
|
|
323
376
|
/**
|
|
324
|
-
* A generic schema allowing
|
|
377
|
+
* A generic schema allowing nested schemas, {@link SchemaEntry} values, or arrays of {@link SchemaEntry} as values
|
|
325
378
|
*/
|
|
326
379
|
type PlainSchema = {
|
|
327
380
|
[key: string]: PlainSchema | SchemaEntry | SchemaEntry[] | undefined;
|
|
@@ -346,11 +399,11 @@ type Schema = SchemaIndex;
|
|
|
346
399
|
/**
|
|
347
400
|
* A union of all valid types for a single schema entry
|
|
348
401
|
*
|
|
349
|
-
* Can be a {@link Constructor},
|
|
402
|
+
* Can be a {@link Constructor}, {@link PlainSchema}, {@link SchemaProperty}, {@link Schematic}, {@link ValueName} string, or a custom validator function
|
|
350
403
|
*/
|
|
351
404
|
type SchemaEntry = Constructor | PlainSchema | SchemaProperty | Schematic<unknown> | ValueName | ((value: unknown) => boolean);
|
|
352
405
|
/**
|
|
353
|
-
* Index signature interface backing {@link Schema}, allowing string-keyed entries of {@link
|
|
406
|
+
* Index signature interface backing {@link Schema}, allowing string-keyed entries of {@link PlainSchema}, {@link SchemaEntry}, or arrays of {@link SchemaEntry}
|
|
354
407
|
*/
|
|
355
408
|
interface SchemaIndex {
|
|
356
409
|
[key: string]: PlainSchema | SchemaEntry | SchemaEntry[];
|
|
@@ -395,7 +448,7 @@ type SchemaPropertyType = Constructor | PlainSchema | Schematic<unknown> | Value
|
|
|
395
448
|
*
|
|
396
449
|
* Each key may hold a single validator or an array of validators that receive the typed value
|
|
397
450
|
*
|
|
398
|
-
* @template Value
|
|
451
|
+
* @template Value `$type` value(s) to derive validator keys from
|
|
399
452
|
*
|
|
400
453
|
* @example
|
|
401
454
|
* ```ts
|
|
@@ -410,8 +463,8 @@ type PropertyValidators<Value> = { [Key in ExtractValueNames<Value>]?: ((value:
|
|
|
410
463
|
/**
|
|
411
464
|
* Removes duplicate types from a tuple, preserving first occurrence order
|
|
412
465
|
*
|
|
413
|
-
* @template Value
|
|
414
|
-
* @template Seen
|
|
466
|
+
* @template Value Tuple to deduplicate
|
|
467
|
+
* @template Seen Accumulator for already-seen types _(internal)_
|
|
415
468
|
*
|
|
416
469
|
* @example
|
|
417
470
|
* ```ts
|
|
@@ -423,7 +476,7 @@ type DeduplicateTuple<Value extends unknown[], Seen extends unknown[] = []> = Va
|
|
|
423
476
|
/**
|
|
424
477
|
* Recursively extracts {@link ValueName} strings from a type, unwrapping arrays and readonly arrays
|
|
425
478
|
*
|
|
426
|
-
* @template Value
|
|
479
|
+
* @template Value Type to extract value names from
|
|
427
480
|
*
|
|
428
481
|
* @example
|
|
429
482
|
* ```ts
|
|
@@ -435,27 +488,27 @@ type ExtractValueNames<Value> = Value extends ValueName ? Value : Value extends
|
|
|
435
488
|
/**
|
|
436
489
|
* Determines whether a schema entry is optional
|
|
437
490
|
*
|
|
438
|
-
* Returns `true` if the entry is a {@link SchemaProperty}
|
|
491
|
+
* Returns `true` if the entry is a {@link SchemaProperty} with `$required` set to `false`; otherwise returns `false`
|
|
439
492
|
*
|
|
440
|
-
* @template Value
|
|
493
|
+
* @template Value Schema entry to check
|
|
441
494
|
*/
|
|
442
495
|
type IsOptionalProperty<Value> = Value extends SchemaProperty ? Value['$required'] extends false ? true : false : false;
|
|
443
496
|
/**
|
|
444
|
-
* Extracts the last member from a union type by leveraging
|
|
497
|
+
* Extracts the last member from a union type by leveraging contravariance of function parameter types
|
|
445
498
|
*
|
|
446
|
-
* @template Value
|
|
499
|
+
* @template Value Union type
|
|
447
500
|
*/
|
|
448
501
|
type LastOfUnion<Value> = UnionToIntersection<Value extends unknown ? () => Value : never> extends (() => infer Item) ? Item : never;
|
|
449
502
|
/**
|
|
450
503
|
* Extracts keys from an object type that are optional
|
|
451
504
|
*
|
|
452
|
-
* @template Value
|
|
505
|
+
* @template Value Object type to inspect
|
|
453
506
|
*/
|
|
454
507
|
type OptionalKeys<Value> = { [Key in keyof Value]-?: {} extends Pick<Value, Key> ? Key : never }[keyof Value];
|
|
455
508
|
/**
|
|
456
509
|
* Extracts keys from an object type that are required _(i.e., not optional)_
|
|
457
510
|
*
|
|
458
|
-
* @template Value
|
|
511
|
+
* @template Value Object type to inspect
|
|
459
512
|
*/
|
|
460
513
|
type RequiredKeys<Value> = Exclude<keyof Value, OptionalKeys<Value>>;
|
|
461
514
|
/**
|
|
@@ -463,8 +516,8 @@ type RequiredKeys<Value> = Exclude<keyof Value, OptionalKeys<Value>>;
|
|
|
463
516
|
*
|
|
464
517
|
* Used by {@link UnwrapSingle} to allow schema types in any order for small tuples _(length ≤ 5)_
|
|
465
518
|
*
|
|
466
|
-
* @template Tuple
|
|
467
|
-
* @template Elput
|
|
519
|
+
* @template Tuple Tuple to permute
|
|
520
|
+
* @template Elput Accumulator for the current permutation _(internal; name is Tuple backwards)_
|
|
468
521
|
*
|
|
469
522
|
* @example
|
|
470
523
|
* ```ts
|
|
@@ -478,9 +531,9 @@ type TuplePermutations<Tuple extends unknown[], Elput extends unknown[] = []> =
|
|
|
478
531
|
*
|
|
479
532
|
* Used internally by {@link TuplePermutations}
|
|
480
533
|
*
|
|
481
|
-
* @template Items
|
|
482
|
-
* @template Item
|
|
483
|
-
* @template Prefix
|
|
534
|
+
* @template Items Tuple to remove from
|
|
535
|
+
* @template Item Index as a string literal
|
|
536
|
+
* @template Prefix Accumulator for elements before the target _(internal)_
|
|
484
537
|
*/
|
|
485
538
|
type TupleRemoveAt<Items extends unknown[], Item extends string, Prefix extends unknown[] = []> = Items extends [infer Head, ...infer Tail] ? `${Prefix['length']}` extends Item ? [...Prefix, ...Tail] : TupleRemoveAt<Tail, Item, [...Prefix, Head]> : Prefix;
|
|
486
539
|
/**
|
|
@@ -488,7 +541,7 @@ type TupleRemoveAt<Items extends unknown[], Item extends string, Prefix extends
|
|
|
488
541
|
*
|
|
489
542
|
* Uses the contravariance of function parameter types to collapse a union into an intersection
|
|
490
543
|
*
|
|
491
|
-
* @template Value
|
|
544
|
+
* @template Value Union type to convert
|
|
492
545
|
*
|
|
493
546
|
* @example
|
|
494
547
|
* ```ts
|
|
@@ -502,8 +555,8 @@ type UnionToIntersection<Value> = (Value extends unknown ? (value: Value) => voi
|
|
|
502
555
|
*
|
|
503
556
|
* Repeatedly extracts the {@link LastOfUnion} member and prepends it to the accumulator
|
|
504
557
|
*
|
|
505
|
-
* @template Value
|
|
506
|
-
* @template Items
|
|
558
|
+
* @template Value Union type to convert
|
|
559
|
+
* @template Items Accumulator for the resulting tuple _(internal)_
|
|
507
560
|
*
|
|
508
561
|
* @example
|
|
509
562
|
* ```ts
|
|
@@ -517,7 +570,7 @@ type UnionToTuple<Value, Items extends unknown[] = []> = [Value] extends [never]
|
|
|
517
570
|
*
|
|
518
571
|
* For tuples of length 2–5, returns all {@link TuplePermutations} to allow types in any order. Longer tuples are returned as-is
|
|
519
572
|
*
|
|
520
|
-
* @template Value
|
|
573
|
+
* @template Value Tuple to potentially unwrap
|
|
521
574
|
*
|
|
522
575
|
* @example
|
|
523
576
|
* ```ts
|
|
@@ -527,20 +580,11 @@ type UnionToTuple<Value, Items extends unknown[] = []> = [Value] extends [never]
|
|
|
527
580
|
*/
|
|
528
581
|
type UnwrapSingle<Value extends unknown[]> = Value extends [infer Only] ? Only : Value['length'] extends 1 | 2 | 3 | 4 | 5 ? TuplePermutations<Value> : Value;
|
|
529
582
|
/**
|
|
530
|
-
*
|
|
583
|
+
* A union of valid type name strings, e.g. `'string'`, `'number'`, `'date'`
|
|
531
584
|
*/
|
|
532
585
|
type ValueName = keyof Values;
|
|
533
586
|
/**
|
|
534
|
-
* Maps
|
|
535
|
-
*
|
|
536
|
-
* Used by the type system to resolve {@link ValueName} strings into actual types
|
|
537
|
-
*
|
|
538
|
-
* @example
|
|
539
|
-
* ```ts
|
|
540
|
-
* // Values['string'] => string
|
|
541
|
-
* // Values['date'] => Date
|
|
542
|
-
* // Values['null'] => null
|
|
543
|
-
* ```
|
|
587
|
+
* Maps {@link ValueName} strings to their TypeScript equivalents
|
|
544
588
|
*/
|
|
545
589
|
type Values = {
|
|
546
590
|
array: unknown[];
|