Replacing Runtime Validation With TypeScript

Terris Linenbach
2 min readFeb 28, 2021

--

Does your JavaScript project validate inputs using Joi or a similar schema validator? Do you want to declare types using more-standard TypeScript without forcing your users to switch to TypeScript?

Unfortunately, you can’t. The JavaScript community is instead migrating toward TypeScript, preferring static typing over runtime validation because it’s more efficient. Since validation is expensive, you should use it only when you need it; for example, when reading JSON files from untrusted sources.

If your users want the benefits of TypeScript, such as a better IDE experience and fewer bugs, they will need to install TypeScript as a dev dependency and make a few additional tweaks to their project. It isn’t hard but it takes some time.

But what about data that arrives over the network or is stored in JSON files? For every interface you publish, you can provide a validator for common use cases. The most common use case is a constructor that accepts a single complex object for initialization. Even vanilla JavaScript can use it.

Rather than passing an untyped object to a function as your users do today, they would instead:

1. Create a generic object (e.g. via JSON.parse)

2. Invoke a validator which returns a typed value

3. Use the validator’s output

ts.data.json is the best validator that I’ve used so far but it is not the most popular library compared to ajv and zod which seem to be better supported.

Ideally, the types that you pained to declare in TypeScript would be reusable when defining validation schemas. However, there’s a difference between document structure and type definitions. Documents have top-level structures that don’t exist in the type system. For example, JSON can represent an array of objects. Also, because type definitions can change, it is sometimes necessary to read old documents into new type definitions. Therefore, declaring separate schemas may be simply unavoidable.

--

--