Runtime validation of TypeScript interfaces
MIT License
ts-audit
is a Typescript transform plugin that verifies external data
structures match what you expect them to be inside your typescript ecosystem.
Typescript's safety guarentees can only work on data that originated inside your
code. Performing a type assertion on a JSON object downloaded from an external
API or library can lead to odd, hard to debug, runtime errors that Typescript
would otherwise have prevented at compile time. ts-audit
solves that by
verifying that external data structures match the structure of the types inside
your system before you can start to interact with them. What this provides is a
barrier between your safe and unsafe code and clearly shows when untyped data
doesn't match your expections. We can't stop mismatched expectations from
occurring at runtime, but we can do is isolate where they can occur and provide
clear indicators of where a mismatch occured and why.
Please read and understand the known issues before consuming. We're working to fix these issues, but in the meantime, you may have to adapt your project's workflow to utilize this project effectively.
You'll need to install two packages, ts-audit
and ttypescript
which is used
to run the transform plugin. (You'll still need typescript
as ttypescript
uses whatever version of typescript
you have installed)
npm install --save-dev ts-audit ttypescript
Your tsconfig.json
will need to be modified to use ts-audit
during the
compilation process.
{
"compilerOptions": {
/* Basic Options */
"plugins": [
{
"transform": "ts-audit",
}
],
/* ... */
}
}
Finally, you'll need to change your build setup to use ttsc
instead of tsc
.
And you're ready to go!!!!!!
All you have to do to use ts-audit
is use assertIsType
or isType
from the library, making sure to annotate the type of the assigned value.
import { assertIsType } from 'ts-audit';
enum Animal {
Cat = 'cat',
Dog = 'dog',
Goat = 'goat',
}
interface UserData {
username: string;
phoneNumber: string;
age: number;
pet: Animal;
notes?: string;
}
const fredsData: UserData = assertIsType(await fetchUser('fred'));
const rawData: unknown = await fetchUser('jake');
if (isType<UserData>(rawData)) {
// rawData is typeGuarded as UserData if true
assert(rawData.username === 'jake');
}
In this example fetchUser
hits an API that returns a JSON object that we
expect to match UserData. If the object matches correctly, then we can use it
safely in our system using the power of the typescript type-system. If there's
a mispelling, missing required key, or type-mismatch we'll throw a runtime error
indicating that the JSON returned does not match what we were expecting.
This does not work for classes, functions, or pretty much anything else that's not supported by JSON-schema. The type sent to validateFunction must be a concrete type. This will NOT work if given a generic argument. ALSO, this has only been tested in a node environment. This may require some additional work to get it working in the browser, but it should be pretty close already if not. JSON schema allow some forms of validation (such as string length) that this tool currently does not.
These are some known issues. There may be more unknown...
ts-audit
.ts-audit
library.incremental
mode.typechecker
issues when using ts-node.
ttsc --outDir=.test
and then run your test framework from there.ttsc --outDir=.test && nyc mocha --reporter=dot ".test/**/*.spec.js"
Overview of the project via directory structure. May help you understand how the code works.
/src
- Source for the transformer
/src/astGenerators
- Functions that generate the AST to be output in the runtime./src/utils
- Various utilities for making code more DRY and readable. This needs some love./src/transforms
- The code that transforms that validation calls inline to use the runtime./src/buildRuntimeValidator.ts
- Given the schema definitions, this is responsible/src/config.ts
- Global configuration values that should eventually be made user-config./src/errors.ts
- Util for building up user-friendly error list for compile-time issuests-audit
that typescript doesn't report./src/main.ts
- Entry point for typescript compiler to invoke the transformer/src/schemaDB.ts
- Class that contains all definitions of types being runtime-checked./src/validationVisitor.ts
- The code which visits all the nodests-audit
functions/imports and transforming them correctly./tests
- Tests testing the transformer and schema validation
/tests/valid
- Tests that build and run to completion (including testing bad schemas)/tests/invalid
- A series of files that should fail at build time.npm test