ts-interface-loader
ts-interface-loader copied to clipboard
Webpack support for validating TypeScript definitions at runtime.
Validate TypeScript definitions at runtime with webpack and Node 8+. Built and used at Spotify.
Common use cases:
- Provide validation for JSON files (i.e. system config)
- Testing JSON output using your existing TypeScript definitions.
Intro
By design, TypeScript only provides typechecking at compile time. However it is possible to do so at runtime through ts-interface-builder
generating a JSON manifest of your definitions and ts-interface-checker
for validating those types with plain JSON / JavaScript objects.
In our case, we wanted to build the manifest automatically through Webpack. Welcome ts-interface-loader
!
Code Example
How does it look like in code terms?
// First, we'll want to make some TypeScript definitions.
// In this case, we have a types.ts with a IUser type interface.
//
export interface IUser {
first_name: string
last_name: string
office_location: 'stockholm' | 'gothenburg' | 'london' | 'new york' | 'boston'
}
// Secondly, we'll write our app.ts (which will run with Webpack)
//
import {createCheckers, ITypeSuite} from 'ts-interface-checker'
import typesTI from 'ts-interface-loader!./types'
// import {IUser} from './types'
const validPayload = {first_name: 'Daniel', last_name: 'Ek'}
const invalidPayload = {first_name: 'Daniel', last_name: 123}
try {
createCheckers(typesTI).IUser.check(invalidPayload)
} catch (err) {
console.log(err.message) // => "value.last_name is not a string"
}
// Or, if we want to validate in "strict" mode
// It's the same as above, except column presence is required.
//
const validStrictPayload = {first_name: 'Daniel', last_name: 'Ek', office_location: 'stockholm'}
const invalidStrictPayload = {first_name: 'Daniel', last_name: 'Ek'}
try {
createCheckers(typesTI).IUser.strictCheck(invalidStrictPayload)
} catch (err) {
console.log(err.message) // => "value.office_location is missing"
}
For a more in-depth sample, take a look at our sample project.
Getting started
Install
$ npm install --dev ts-interface-loader
$ yarn add --dev ts-interface-loader
Import ts-interface-loader
in your TypeScript code (.ts
or .tsx
)
// ES6 Modules
import typesTI from 'ts-interface-loader!./types'
// ES5 (CommonJS)
const typesTI = require('ts-interface-loader!./types')
Note: Using
tsc
ortslint
? You'll need to add@ts-ignore
andtslint:disable-line:no-implicit-dependencies
for now, as there is no support (natively or through plugins) for supporting importing webpack loaders inline.// @ts-ignore import typesTI from 'ts-interface-loader!./types' // tslint:disable-line
Development
Clone the repository
$ git clone https://github.com/spotify/ts-interface-loader.git
$ cd ts-interface-loader/
$ yarn install
Run
# Get started
$ yarn build
$ cd example/
$ yarn watch
# Run some commands!
$ cat src/__fixtures__/ok-all-matching-types.json | yarn run --silent cli | jq '.manifestJson'
$ cat src/__fixtures__/error-no-tvshows-key.json | yarn run --silent cli | jq '.manifestValidator'
$ cat src/__fixtures__/error-no-tvshows-key.json | yarn run --silent cli | jq '.manifestStrictValidator'
# Take a look at other fixtures!
$ cd src/__fixtures__
Test
Run the following command
$ yarn test
Changelog
v1.0.2
Fixed security bugs with:
-
mixin-deep
by bumping from1.3.1
to1.3.2
-
set-value
by bumping from2.0.0
to2.0.1
-
serialize-javascript
by bumping from1.4.0
to2.1.1
v1.0.1
Fixed security bug with handlebars
by bumping from 4.1.2
to 4.5.3
v1.0.0
Initial release
Contributing
We strictly adhere to the Contributor Covenant in this repository, and wish to foster an open source culture that's welcoming and diverse.
Pull requests and stars are always welcome. For bugs and feature requests, please create an issue.
- Fork it!
- Create your feature branch:
git checkout -b my-new-feature
- Commit your changes:
git commit -am 'Add some feature'
- Push to the branch:
git push origin my-new-feature
- Submit a pull request :)