New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details →
Socket
Book a DemoSign in
Socket

data-type-ts

Package Overview
Dependencies
Maintainers
1
Versions
11
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

data-type-ts

Runtime typed data validation for TypeScript.

latest
Source
npmnpm
Version
1.0.3
Version published
Maintainers
1
Created
Source

Runtime Data Types for TypeScript

Getting Started

npm install --save data-type-ts

You can define types at runtime that are correctly inferred by TypeScript.

const schema = t.object({
	id: t.string,
	role: t.union(t.literal("admin"), t.literal("member")),
	settings: t.map(t.boolean),
	friends: t.array(t.string),
	rest: t.tuple(t.number, t.string, t.null_, t.undefined_, t.any),
	age: t.optional(t.number),
})

type Schema = t.Infer<typeof schema>
// type Schema = {
// 	id: string
// 	role: "admin" | "member"
// 	settings: {
// 		[key: string]: boolean
// 	}
// 	friends: string[]
// 	rest: [number, string, null, undefined, any]
// 	age?: number | undefined
// }

You can validate values with useful error messages:

schema.is({
	id: "",
	role: "admin",
	settings: {},
	friends: [],
	rest: [1, "", null, undefined, {}],
})
// true

t.formatError(
	schema.validate({
		id: "",
		role: "editor",
		settings: {},
		friends: [],
		rest: [1, "", null, undefined, {}],
	})!
)
// .role: "editor" must satisfy one of:
// 	"editor" is not "admin"
// 	"editor" is not "member"

If you prefer to define your types normally and only use this library for validation, you can still get typesafety this way:

type Schema = {
	id: string
	role: "admin" | "member"
	settings: {
		[key: string]: boolean
	}
	friends: string[]
	rest: [number, string, null, undefined, any]
	age?: number | undefined
}

// Type conformation:
const schema: t.Validator<Schema> = t.object({
	id: t.string,
	role: t.union(
		t.literal("admin"),
		t.literal("member"),
		t.literal("editor") // This should make an error.
	),
	settings: t.map(t.boolean),
	friends: t.array(t.string),
	rest: t.tuple(t.number, t.string, t.null_, t.undefined_, t.any),
	age: t.optional(t.number),
})

There are two gotchas with this approach though:

  • The type errors are pretty hard to interpret when things aren't lined up.

  • This approach does not catch missing optional types for fundamental TypeScript reasons.

     ```ts
     const schema: t.Validator<Schema>  = t.object({
     	id: t.string,
     	role: t.union(t.literal("admin"), t.literal("member")),
     	settings: t.map(t.boolean),
     	friends: t.array(t.string),
     	rest: t.tuple(t.number, t.string, t.null_, t.undefined_, t.any),
     	// age: t.optional(t.number), // This should throw and error but it doesnt!
     })
     ```
    

Custom Types

This library only supports the most basic JSON types but you can extend it with your own custom validators:

function range(min: number, max: number) {
	return new t.Validator<number>({
		validate: value =>
			t.number.validate(value) || value < min
				? { message: `${value} is less than ${min}`, path: [] }
				: value > max
				? { message: `${value} is greater than ${max}`, path: [] }
				: undefined,
		inspect: () => `${min} >= number >= ${max}`,
	})
}

import * as emailValidator from "email-validator"

export const email = new t.Validator<string>({
	validate: value =>
		t.string.validate(value) || !emailValidator.validate(email)
			? { message: `${JSON.stringify(value)} is not valid email` }
			: undefined,
	inspect: () => "Email",
})

const schema = t.object({
	id: t.string,
	email: email,
	score: range(0, 10)
})

console.log(schema.toString())
// {
// 	id: string,
// 	email: Email
// 	score: 0 >= number >= 10
// }

Note that the inspect argument is optional but it's is helpful for debugging.

Keywords

runtime

FAQs

Package last updated on 29 Nov 2023

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts