Typescript check object by type or interface at runtime with typeguards in 2020+

There are actually a number of modules which attempt to translate TypeScript type information into runtime information that can be used to validate data structures.

I’ll attempt to list and compare the various solutions here. (ordered roughly by how effective/general-purpose I estimate them to be; yes, this is somewhat subjective!)

Core features: (marked with ✔️yes, ❌no, ⚙️partial, ❔unknown)

ts-base TS base: Standard TypeScript types are used as the basis for the type-metadata. (rather than vice-versa)
class Classes: Can generate type-metadata for classes (based on shape, not instanceof), rather than just interfaces.
func Functions: Can generate type-metadata for functions.
guard Type-guards: Includes functions to validate runtime data against the type-metdata. (ie. type-guards)
auto Auto-check: Can automatically generate invocations of the included type-guards.

Solutions

typescript-is

GitHub: 500
NPM: 2,555
(2020-09-30)

Core features:
ts-base: ✔️
class: ❌
func: ❌
guard: ✔️
auto: ⚙️
Note: Auto-check marked as partial, since you can add decorators to class-methods (but not standalone functions) to have their argument types checked.

typescript-json-schema (+ a schema validator, eg. ajv)

GitHub: 1,400
NPM: 51,664
(2020-09-30)

Core features:
ts-base: ✔️
class: ✔️
func: ❌
guard: ❌
auto: ❌
Pro: Generates valid json-schemas, which have additional uses. (eg. can be used for data validation in other languages)
Con: Requires some manual work to write generated schemas to disk, package them to be available at runtime, and feed them to your selected JSON-schema validator.

typescript-rtti

GitHub: 54
NPM: 648
(2022-03-09)

Core features:
ts-base: ✔️
class: ✔️
func: ✔️
guard: ❌
auto: ❌
Pro: Provides rich metadata about the TypeScript types, that is usable for functionality beyond type-guards.

tst-reflect

GitHub: 77
NPM: 79
(2022-03-09)

Core features:
ts-base: ✔️
class: ✔️
func: ✔️
guard: ❌
auto: ❌
Pro: Provides rich metadata about the TypeScript types, that is usable for functionality beyond type-guards.

ts-runtime

GitHub: 313
NPM: 96
(2020-09-30)

Core features:
ts-base: ✔️
class: ✔️
func: ✔️
guard: ✔️
auto: ✔️
Con: Cannot currently be applied to only specific files or functions; it adds type-guard invocations throughout the project. (but PRs appear welcomed)
Con: Contains the note: “This package is still experimental and resulting code is not intended to be used in production. It is a proof of concept…”

io-ts (alone)

GitHub: 3,600
NPM: 296,577
(2020-09-30)

Core features:
ts-base: ❌
class: ❌
func: ❌
guard: ✔️
auto: ❌
Pro: Doesn’t require any typescript transformers, webpack plugins, or CLI commands to operate. (it uses “tricks” to infer the TS types from its custom type-definition structure)

io-ts-transformer (extension for io-ts)

GitHub: 16
NPM: 7
(2020-09-30)

Core features:
ts-base: ✔️
class: ❌
func: ❌
guard: ✔️
auto: ❌

ts-auto-guard

GitHub: 134
NPM: 46
(2020-09-30)

Core features:
ts-base: ✔️
class: ❔
func: ❌
guard: ✔️
auto: ❌
Con: You must add a specific js-doc tag to each interface you want a type-guard generated for. (a hassle, and error prone)

typeonly

GitHub: 25
NPM: 101
(2020-09-30)

Core features:
ts-base: ✔️
class: ❔
func: ❌
guard: ✔️
auto: ❌
Con: Cannot generate type-guards for generic types. (see here)

ts-type-checked

GitHub: 13
NPM: 3
(2020-09-30)

Core features:
ts-base: ✔️
class: ❔
func: ❌
guard: ✔️
auto: ❌

Not yet evaluated: ts-json-schema-generator, typescript-to-json-schema, gfx/typescript-rtti
Excluded (no public repo): typescript-runtime-types

Disclaimer

I am not the creator or maintainer of any of the solutions listed. I created the list to help developers compare the various solutions, on a consistent set of criteria, while adding helpful information such as GitHub stars and NPM weekly downloads. (edits are welcome to periodically keep these values up-to-date — though remember to change the last-update-time labels!)

For those with enough reputation, feel free to add additional solutions that you come across. (though please try to keep the text for your new entries consistent with the existing ones)

Leave a Comment