type-guards
This module allows you to write run-time validation in a clear way in a strongly-typed manner. In other words, it gives you a nice way to keep your code DRY by writing the validation function, and get the TypeScript types with it.
Installation
$ yarn add type-guards
Examples
// we purposely mark it as "any" to imitate API response or user's input// (anything generated at runtime which we cannot give a static type to) if isUserjohn
List of functions
is
Create a validator that asserts that the given argument is strictly equal (===
) to something.
Not very useful on its own.
isOneOf
Create a validator that asserts that at least one of the validators passed as arguments are passing.
isAbc'a' // => trueisAbc'b' // => trueisAbc'c' // => trueisAbc'd' // => false
isEnum
Create a validator that asserts that the given arguments is exactly one of the given arguments. For example, the validator form the previous example can be written in a more simple way.
If all the arguments are of the same type, it will be inferred; so the above example will assert for string. If you have an enum, list all its values somehow in an array, and use the spread operator to pass the values in.
isNull
A validator that asserts that the given argument is null
. Short for is(null)
isUndefined
A validator that asserts that the given argument is undefined
. Short for is(undefined)
.
isNullOrUndefined
, isNullish
A validator that asserts that the given argument is null
or undefined
(like doing arg == null
).
Short for isOneOf(is(null), is(undefined))
.
An alias with a shorten yet recognizable name is isNullish
.
isNotNull
, isNotUndefined
, isNotNullOrUndefined
, isNotNullish
The opposite of the previous three validators.
A common use-case is filtering an array to get rid of nullish values:
// type of `filtered` is `Array<number>`
Doesn't work perfectly with the else
branch, but this is a less common use-case. Either way, help is appreciated in the SO thread if you know more about this.
isOfBasicType
Create a validator that asserts that the given argument is of a certain type.
This is a wrapper around typeof
checks and works with string
, number
, boolean
, symbol
, function
and object
.
isString
, isNumber
, isBoolean
, isSymbol
, isObject
, isFunction
.
Validators that assert that the given argument is of the correct type.
Short for isOfBasicType('string')
, isOfBasicType('number')
, etc.
Instead of isObject
, you probably need isShapeOf
instead, which gives you more control over the type.
isInstanceOf
Create a validator that asserts that utilized the mechanism of instanceof
keyword in JavaScript.
isArrayOf
Create a validator that asserts the given argument is an array,
where each of its item is of a certain type.
The type of the items is passed as the argument of isArrayOf
.
areNumbers // => trueareNumbers1 // => falseareNumbers // => falseareNumbers // => false
Of course, feel free to combine validators.
areNumbers // => trueareNumbers // => true
isOfShape
Create a validator that asserts that the given argument is an object,
where each of the values of its keys correspond to the given shape.
The shape is an object where the values are either new shapes or simple type checks.
isOfShape
allows objects that have extra keys. See isOfExactShape
to exclude
objects having extra keys not defined by the shape.
isUser // => trueisUser // => falseisUser // => trueisUser // => false isCompany
isOfExactShape
The same as isOfShape
, except that it excludes objects that have extra keys
not defined by the shape.
isUser // => trueisUser // => falseisUser // => falseisUser // => false
isTuple
Create a validator that asserts that passed argument is a tuple of certain elements.
isNamePair // => trueisNamePair'Gustavo' // => falseisNamePair // => falseisNamePair // => false
pick
Create a validator which utilizes an already created validator and picks only a part of it.
// the two consts above produce the same validator
omit
Create a validator which utilizes an already created validator and omits a part of it.
// the two consts above produce the same validator
partial
Create a validator which utilizes an already created validator but allows undefined
for every value.
// the two consts above produce the same validator
Note, however:
partOfUser // => truepartOfUser // => false (missing "age")partOfUser true
Currently working on making the second one return true
as well.
Using the type only
If you do not need to use the validator, but only want the type information, you can do that as well.
This means that your codebase can have validators "just in case", but if you never use them, it will not increase your bundle size. You could also set up your build pipeline in such way that the validators are run only in development mode.
Run-time assertion
You usually want to throw an exception at run-time in case the state of the application becomes unexpected.
For example, you might have public foo?: string
in the class, but at some place you're certain that foo
must be defined.
Instead of doing this.foo!
, which is just a build-time assertion, you might want to perform a run-time assertion such as the following.
if this.foo === undefined
TypeScript will properly assert here that this.foo
is Exclude<string | undefined, undefined>
below the if
block, which boils down to string
.
However, this becomes quite annoying to write all the time.
Hence, throwIf
helper.
Or, create a reusable function. This is the recommended way.