Utilities are special kind of concept that allows by very hacky way of implementing Utility Types a-like types for validation. Currently, tsruntime does not implement reflection of TypeScript's Utility Types, however simple generics structures are supported.
We (ab)use this to create objects, that serves a purpose of container that hold their utility type and payload:
exporttype $PropsOf<T>={
__eveble_validation:'propertiesOf';
__eveble_payload:T;
};
So when we use:
check<$PropsOf<MyClass>>();
The class constructor becomes the payload.
Please fallow this guide when defining new generic utility types:
Use PascalCase with $ prefix for naming of types so they are not mistaken as native build-inTypeScript types:
First, we ensure that kind of reflectedType is pointing out to object(i.e. the number 15) and validationType is indeed set to whatever value we assigned it previously under __eveble_validation on our generic $PropsOf type.
Then, we ensure that our payload can be converted by class converter - since the purpose of $PropsOf utility is to generate pattern - that will allow for validation of required properties for class construction.
Next, we need to implement convert methods on our PropsOfConverter:
tsruntime by default will reflect nested structures to their own reflected types, so we resolve TypeConverter for class from our converter and pass that reflected type for conversion.
Class converter will return Class pattern with assigned properties: type as provided class constructor and properties as the class definition. Since we are interested only with properties - we return that in form of new Collection pattern.
TypeConverter additionally also requires reflect to method to be implemented so we do exactly that:
Having utility type and TypeConverter is enough to start building validator - however, if you intend to support also JavaScript validation creating new Utility is necessary:
We use WrapperPattern as our base class so our structures are easier to debug. We validate that provided type on construction is indeed a class type and assign it on 0 index.
Utilities(types.Utility) for JavasScript require generate method to be implemented that should return the expectation for validation. You can use whole Typend features on generation:
Our $PropsOf(TS) and PropsOf(JS) will use already existing validator without necessity of implementing our own.
Of course on PropsOfConverter and PropsOf utility we can always return a new, not-existing Pattern implementation and dedicate a new PatternValidator for handling it.