npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

runruntypes

v0.1.0

Published

A poor man's runtime-only type checker

Readme

RunRunTypes

RunRunTypes is a simple runtime-only type checker. It's a fairly specific and simple library and it might be for you if:

  • You're trying to write a runtime-less app and need type checking in development
  • Your types are not simple and you prefer Flow-like definitions for them
  • You don't care about Flow's comment-only syntax much

Well, if you belong to this small exclusive club, then Welcome!

Disclaimer: This is frankly a horrible idea that's not meant for real world stuff, but it's been quite fun to write.

Getting Started

You can install RunRunTypes like any other npm package:

yarn add --dev runruntypes
# or
npm install --save-dev runruntypes

NOTE: It's recommended to not ship this package in production as it pulls in @babel/parser as a dependency, which is really not that small. It's fairly simple to stub out this library's API though.

Usage

RunRunTypes consists of two easy to use functions, gen and type.

import { gen, type } from 'runruntypes';

The gen function is used to attach a type signature to your function. Using this signature you can constrain the arguments' types and the function's return type. The gen function will wrap your function and return one that performs the checks when called. A signature is basically a Flow type annotation:

const fn = gen`
  (string, number, number) => [string, number]
`((str, a, b) => [str, a + b])

fn('test', 1, 2) // returns: ['test', 3]
fn('test', 1) // error!
fn(1, 1, 1) // error!

The above example shows a simple definition and how arguments are checked. Similarly the return types are checked when your function completes:

const fn = gen`
  (string, number, number) => [string, number]
`((str, a, b) => null)

fn('test', 1, 2) // error!

The second function, type is used to alias type signatures to a variable. It can be used to predefine some types which can then be interpolated into your gen definition.

import { gen, type } from 'runruntypes';

const Errorish = type`
  { message: ?string }
`;

const isError = gen`(${Errorish} | void) => bool`(err => {
  return err !== undefined && !!err.message;
});

This extracts an object definition type outside of the gen definition. For comparison, without a type alias you'd simply write this definition inline, which can become tedious if it's being used and repeated quite often:

import { gen } from 'runruntypes';

const isError = gen`
  ({ message: ?string } | void) => bool
`(err => {
  return err !== undefined && !!err.message;
});

RunRunTypes uses the @babel/parser to parse any input to it. A large subset of Flow type annotations will be parsed without a problem and will be correctly check. You can always expect this library to throw a TypeError when it either:

  • doesn't understand your type definition
  • or; has caught a type error

Feel free to read more about Flow type annotations here

API

type

A tagged template literal that accepts a Flow type definition consisting of any of the supported types and syntax.

This will return a function that checks the first argument against the type definition and returns true if it passes the type checks and false if it doesn't.

type`string`('test') // true
type`{ x: 1 }`({ x: 2 }) // false

gen

A tagged template literal that accepts a Flow arrow function type definition consisting of any of the supported types and syntax.

It expects any number of arguments and a return type. Normal type definitions that are not function definitions will cause it to throw an error.

It returns a factory function that wraps any function passed as the first argument in a new type checked and guarded function, i.e. it'll expect the argument to comply to the type definition that has been defined and will enforce it.

gen`string => string`(x => 'Hello, ' + x)('Luke')
gen`(number, 4) => string`((a, b) => '' + a + b)(2, 4)

Supported Types

Currently the following types are supported:

  • primitive types (bool, number, string, null, void, any)
  • literal types (e.g. true, false, 2, "hello")
  • nullables (?number, i.e. null, undefined, number)
  • arrays (number[])
  • tuples ([number, number])
  • objects ({ x: number } without support for optionals nor methods)
  • unions (number | string meaning that both are allowed)
  • intersections ({ x: 1 } & { y: 2 } meaning that both must match)
  • generic constructors (e.g. Date or Element which will simply check the constructor's name)
  • "any" functions or objects (write Object to match any object, Function to match any function)

You can mix and combine the types as you'd expect in a real typed language. Remember that gen expects a function definition and type any of the above.