Currently, the schema is passed as a third parameter for is
:
is([value], [DataType], [options]);
Challenges
The options are too freeform and hard to express.
- They're somehow tied to the DataType, yet separate.
- Options slot encompasses shared options, which can be confusing.
Schema is mixed into options, which adds to the confusion.
- Has both
props
and items
.
- Having the schema as a nested option adds complexity and confusion.
- Schema can be used to describe types other than object—more complexity and confusion.
Transition thoughts
// Tie the options closer to the DataType itself.
// This would more clearly tie options to the type they actually belong to.
is(val, DataType.string({ type_specific_options }));
// For schemas
// Shape would check of obe
is(val, DataType.withShape({
name: DataType.string().required,
age: DataType.number({ min: 0 }).required,
address: DataType.withShape(...)
}));
// For multiple DataTypes
is(val, DataType.oneOf(DataType.string, DataType.number));
For String
// Current is
is(val, DataType.string, {
pattern: string,
patternFlags: string,
exclEmpty: boolean
});
// Transition
// patternFlags would be removed. A regular expression would be used instead.
is(val, DataType.string({ pattern: regexp, empty: boolean }));
For Number
// Current is
is(val, DataType.number, {
multipleOf: number,
min: number,
max: number,
exclMin: number,
exclMax: number
});
// Transition
// Would likely drop exclMin and exclMax. They're too close to min and max.
is(val, DataType.number());
is(val, DataType.number({ min: number, max: number, multiple: number }));
is(val, DataType.integer());
is(val, DataType.natural());
For Array
// Current is
is(val, DataType.array, { type: DataType | DataType[],
min: number,
max: number,
exclMin: number,
exclMax: number,
schema: isTypeSchema | isTypeSchema[] | null })
// Transition
// Would likely drop exclMin and exclMax. They're too close to min and max.
// DataType array in `type` would be replaced by oneOf
// `schema` would be replaced by `withShape`
is(val, DataType.array({ of: DataType, min: number, max: number }))
is(val, DataType.array({ of: DataType.oneOf(DataType.string, DataType.number) }))
is(val, DataType.array({ of: DataType.withShape(...) }))
For Object
// Current is
is(val, DataType.object, { arrayAsObject: boolean,
schema: isTypeSchema | isTypeSchema[] | null })
// Transition
// `arrayAsObject` would be replaced by `oneOf`
is(val, DataType.object())
is(val, DataType.withShape(...))
is(val, DataType.oneOf(DataType.object(), DataType.array()))
Wouldn't change
is(val, DataType.function());
is(val, DataType.boolean());
is(val, DataType.undefined());
is(val, DataType.null());
is(val, DataType.any());
Further departures?
Haven't put much thought into the following. Mostly jotting down ideas.
Shorten DataType
to just Type
?
It would just reduce noise a little bit.
// General pattern
is(val, Type.type({ type_specific_options }));
// Applied
is(val, Type.function());
is(val, Type.boolean());
is(val, Type.undefined());
is(val, Type.null());
is(val, Type.any());
is(val, Type.object()))
is(val, Type.array());
is(val, Type.number());
is(val, Type.string());
is(val, Type.oneOf(Type.object(), Type.array()));
is(val, Type.withShape(...));
Append is
?
The readability of "is [value] DataType" would not make sense anymore: "DataType is [value]".
An alternative word could be found for is
, such as check
, test
, matches
, or something like that.
// General pattern
DataType.type({ type_specific_options }).check(val);
// Applied
DataType.function().check(val);
DataType.boolean().check(val);
DataType.undefined().check(val);
DataType.null().check(val);
DataType.any().check(val);
DataType.object().check(val)
DataType.array().check(val);
DataType.number().check(val);
DataType.string().check(val);
DataType.oneOf(DataType.object(), DataType.array()).check(val)
DataType.withShape(...).check(val)