safe-cast
A typescript library to safely cast unknown or unstructured data to a Typescript type.
1 minute Getting Started guide
To install this library in your own code:
npm install --save safe-cast
yarn add safe-cast
The vast majority of the time you will want to just create a typescript type
and use the safeCast
method.
Create a Typescript Type that you want to cast your data to:
export type TestType = {
id: number;
name: string;
values: {
val1: string,
val2?: string
}
}
Note: Notice the annotations on the type properties (like @maxLength
)? The annotations that you can set here are JSON Schema annotations and they will be honoured by this library. For the full list of supported annotations please see the typescript-json-schema library.
Once your type that you wish to cast to is declared then you can use the safeCast function to cast and validate in the one
safe and secure step:
import { safeCast, CastError } from 'safe-cast';
const testType = safeCast<TestType>("TestType", ['path/to/TestType.ts'], {
id: 1234,
name: 'hi',
values: {
val1: 'woo'
}
});
if (testType instanceof CastError) {
} else {
}
The trickiest part for users of this library to correctly specify is the path to their TS files that they should pass to the second argument of the safeCast
function. This means that, when your program is running, you need to know the path to your uncompiled typescript files so that the safeCast
function can introspect them to read the types. Remember that, when Typescript compiles to Javascript, all of the type information is stripped and it is that type information that the safeCast
function needs to work.
Learn more
A solid base
This library was built, primarily, on top of typescript-json-schema and ajv; these two libraries provide the bulk of the functionality of safe-cast
. This library provides the convenience of joining them together but, as a result, is intentionally a leaky abstraction over these libraries (typescript-json-schema
is "leakier" than ajv
). This is because it is desirable to use the annotations that typescript-json-schema
accepts in your own types.
The dependencies on these two libraries makes much of the logic very robust and fast.
Advanced usage
The safeCast
method is supposed to handle 90% of the expected usage of this library. It is good for the common use cases because:
- Performance
It has internal caching behaviour, making it perform extremely quickly for repeated usage. - Simplicity
You only need to provide four arguments. The Type you wish to cast to, the name of the same type for lookup purposes, the data you are casting to your given type and the set of Typescript files that should be loaded to introspect your types. - Fits your workflow
It is expected that you will already have Typescript types lying around. You should just be able to point the safeCast
function at already existing files / data and expect it to "just work".
Despite those advantages, there may be other cases that cause you to deviate from the safeCast
function.
There are two other classes that may be of interest to you.
-
TypescriptSafeCast
This class is designed to load one or more typescript files and their respective types, convert those types into JSON Schema and then use ajv
to validate the data you are trying to cast against that schema. This is the class that we use to back the safeCast
method.
The benefit of using the TypescriptSafeCast
class is that you can more tightly control the loading and performance of the casting. The constructor for the TypescriptSafeCast
function is slow (on the order of seconds) but the TypescriptSafeCast#cast
method is fast (on the order of milliseconds).
Also, the TypescriptSafeCast
class exposes the ability to pass more fine grained options down to the typscript-json-schema
and ajv
libraries; allowing you to customise behaviour to your needs. More and more features will be exposed through the TypescriptSafeCast
class over time.
-
SchemaSafeCast
The process for TypescriptSafeCast#cast
is: Parse Typescript Types
=> Convert Type To JSON Schema
=> Validate incoming data against JSON Schema
. The first two steps of this flow are slow. Therefore, for those developers that are willing to write and maintain their own JSON Schemas (or want to build them at compile time for use at runtime); we provide the SchemaSafeCast
function. For this function, you just provide a valid JSON Schema in the constructor and then the cast function will do the rest.
Benchmarking shows that the SchemaSafeCast#cast
function is the most performant function in this library by a few orders of magnitude. Use the SchemaSafeCast
if you want blazing speed.
Hopefully this helps you use this library in a way that meets your needs.