Use Generics
What tools are available to replicate TypeScript's generics?
While there isn't a sensible way to directly provide the behavior of TypeScript's generics at runtime, there are various tools and patterns which can be used to replicate different aspects of generics.
Iterable Matching Syntax
TypeScript generics are often used on data structures. Luckily, such data structures will usually implement the iterator protocol to reveal their contents. Knowing this, Moat Maker provides an iterator-matching syntax, which allows you to verify that every value yielded by an iterator matches a particular pattern.
The @<...>
iterable-matching syntax is intended to look similar to TypeScript's generic syntax, because it happens to be able to handle a number of similar cases. But, it's also slightly different (it has the extra @
) to remind us that it operates in a fundamentally different way.
Validator Factories
Iterable matching can't handle all problems. Some objects might contain data of a particular type, but they might not implement an iterator protocol for various reasons.
Imagine, for example, a generic coordinate type whose values can be of type number
, bigint
, or whatever you want them to be.
To create a similar schema definition in Moat Maker, it's recommended to create a "validator factory function", which would allow you to configure how the validator behaves via the parameters it receives.
Just how in TypeScript you can pass in any type into the generic Coordinate
interface to control the type of each field, you can pass any validator instance into createCoordinateValidator()
to control how each field is validated.
validator.from()
To remove some boilerplate of a validator factory, a helper validator.from()
function is provided that can take, as an input, either a string or a validator instance, and will always return a validator. If used against the arguments of your validator factory, you enable users of your factory to pass in a string instead of a validator instance, which can be more convenient.
This is especially useful when you want to compose validator factories inside another validator, without being overly verbose.
Security note: Do not call validator.from()
with untrusted, user-supplied input. We don't want end-users crafting malicious strings that cause the validation algorithm to grind to a halt. It's unlikely that such strings could be built in the current version, but there's no guarantee that features won't be added in the future that enable attacks like these.
Transformers
Last updated