Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@cloudflare/util-en-garde

Package Overview
Dependencies
Maintainers
31
Versions
32
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@cloudflare/util-en-garde

Safely and declaratively create user-defined type guards

  • 6.4.1
  • npm
  • Socket score

Version published
Maintainers
31
Created
Source

En Garde! 🤺

Safely and declaratively create user-defined type guards


User-defined type guards are great, but there be dragons! 🐉

User-defined type guards can help inspect untrusted data (especially from IO) and then have confidence that you can safely do things with it once it has been checked. But just checking the data can be dangerous. Many type guards cast as any which means now you have to be extra careful and think of every possible scenario where a data structure might throw an error if you access it unsafely.

Then there's the problem of ensuring that the type guard stays up to date with the type. Just added a new required field on the interface? Will you get a compiler error if you don't go update your type guard? Even if the answer is "yes" here, you still have to go update it.

What if there was a better way? 🤔

What if safely written type guards written with no casting could be declaratively composed to represent just about any shape?

What if types could be derived from those composed type guards?

What if you could easily bring your own type guards and compose them as well?

Examples

Basic shapes

import eg from 'en-garde'; // 🤺

// (value: unknown) => value is Date | undefined
const isMaybeDate = eg.instanceOf(Date).optional;

// (value: unknown) => value is string[]
const isArrayOfStrings = eg.arrayOf(eg.string);

// (value: unknown) => value is (string | number)[]
const isArrayOfStringsOrNumbers = eg.arrayOf(eg.oneOf(eg.string, eg.number));

/** (value: unknown) => value is {
 *    firstName: string
 *    lastName?: string | undefined
 *    email: string
 *    birthday: Date | null
 *    address:? {
 *      street: string
 *      city: string
 *      state: string
 *      zip?: string | undefined
 *    } | undefined
 *    nickNames?: string[] | undefined
 *    favoritePrimaryColor: "red" | "blue" | "yellow"
 * }
 */
const isPerson = eg.object({
  firstName: eg.string,
  lastName: eg.string.optional,
  email: eg.string,
  birthday: eg.oneOf(eg.instanceOf(Date), eg.null),
  address: eg.object({
    street: eg.string,
    city: eg.string,
    state: eg.string,
    zip: eg.string.optional,
  }).optional,
  nickNames: eg.arrayOf(eg.string).optional,
  favoritePrimaryColor: eg.oneOfLiterals('red', 'blue', 'yellow'),
});

/** Derive type information from the guard!
 *
 * type Person = {
 *    firstName: string
 *    lastName?: string | undefined
 *    email: string
 *    birthday: Date | null
 *    address:? {
 *      street: string
 *      city: string
 *      state: string
 *      zip?: string | undefined
 *    } | undefined
 *    nickNames?: string[] | undefined
 *    favoritePrimaryColor: "red" | "blue" | "yellow"
 * }
 */
export type Person = TypeFromGuard<typeof isPerson>;

Strongly typed API validation

The assertShape helper is especially useful for validating that data from an API is what you expect.

import eg, { assertShape } from 'en-garde';

const isPerson = eg.object({
  firstName: eg.string,
  lastName: eg.string,
});

// type Person = {
//    firstName: string
//    lastName: string
// }
type Person = TypeFromGuard<typeof isPerson>;

// This function returns a promise that will *ONLY* ever
// resolve if the JSON returned is an array of the Person
// type, otherwise it will throw an error that can be caught
// and logged to whatever error monitoring service you use.
const getPeople: () => Promise<Person[]> = () =>
  fetch('www.example.com/api/people')
    .then(res => res.json())
    .then(assertShape(eg.array(isPerson)));

FAQs

Package last updated on 01 Feb 2020

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

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc