ts-rtti
ts-rtti enables typescript static type information to be used for run time type checking.
(Coming soon.)
Interface
It is provided as a plugin for use with ttypescript.
Implementation
Type script type information is parsed and converted opaquely to avj schemas.
The schemas are by default converted to ajv codegen format, which allows for fast execution,
both on the server side (node) and on the broswer.
Features
Types which can be parsed
Files are selected and within those files top level functions are selected for targeting.
The parameter list of those selected functions is treated as a top level ts-rtti run time type.
ts-rtti handles typescript native types:
- Primitives
- number
- string
- bigint
- symbol
- constant primitve values (excepting symbols)
- array
- object
- function (ingoring signature)
- Exception: Selected top level functions are parsed so they can be used as validators of their own arguments.
- class
- Currently instanceof is not implemented. Classes are treated no differently than the interfaces they implement.
- Typescript union (
|
)
- Currently union key merging is propogated only one level deep, whereas typescript goes infinitely deep.
- Typescript intersection (
&
) - All other Typescript types: typescript utilities and user defined types.
ts-rtti allows, via an optional configuration setting, union (|
) and intersection (&
) to be interpreted as logical operators that map one-to-one with json schema anyof
and allof
operators. (This is a global setting, so not generally useful - but there could be specific limited use cases.)
Recurrent Typescript types are handled correctly. ts-rtti handles recursion during parsing, and ajv
allows recurrent schema definitions.
Note: Input data structure recurrence (the data being validated) is handled if and only if ajv
handles that.
A recurrent type definition does not imply the corresponding input data must be recurrent. In general it is not.
ttypesctipt Compilation
ts-rtti module supplied as a plugin which is consumable by ttypescipt.
There are some intermediate typescript source files created by the ts-rtti plugin which contain the ajv
generated code and related interface, all necessary for runtime use.
By default, these typescript source files are not written to disk but are converted from memory directly to javascript output, along with rest of the users compiled output.
However, the user may optionally enable the generation to disk of the ts-rtti intermediate typescript files. Then the entirity could later be compiled without use ttypescipt, just using ordinary typescript instead. (In that case, an extra step is required to deliberately set the import path to the ts-rtti intermediate typescript files.)
ajv
schemas.
As mentioned previously, by default the ajv
schemas are converted to codegen
form, which is faster, and can also be used on the browser. However, the ajv
schema can optionally be saved and used. The codegen
can also be optionally turned off.
Example usage
Future feature candidates
- Parsing of arbitrary top level types, rather than just allowing function signatures.
- Hybrid types that allow blending of typescript types and explicit json-schema structures.
- This would also be a way to implement logical-stype union and interesection in typescript, although the static typing would be missing.
- Custom keys to allow pinpoint validiation conditions.
- Enable export of selected ajv schemas as self-contained output files.
- Faithful computation of typescript union (
|
), allowing arbitrarily deep object type key merging.
- Upside: Although this is not possible to do in
O(1)
size using the normal JSON schema interface, it is possible to implement a virtual stack in parallel to ajv
runtime, and connected to that runtime by means of custom ajv
keys, allowing both O(1)
code size and O(1)
execution time (relative to Typescript native union computation). - Downside: But would there actually a demand for that? The current one-level deep object type key merging may be enough.
- Edit time / language server usage of json schema validation to validate user input when the ts-rtti validation conditions are stronger than (or different from) the conditions (if any) imposed by native Typescipt. This would be ts-rtti used for static typing.
- Downside: A lot of work. Also, there is a complete iteration of
programCreate
between edit of code upon which some json-schema depends, and the update of that json-schema. That could lead to ungainly sluggish UI in those cases. - Upside: It could be very useful for broading type available type syax, e.g., for allowing logical-style union and intersection of object types to get equal treatment under UI.