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

runtypejs

v1.2.0

Published

library allowing run time type validation

Readme

runTypeJs

runTypeJs is a library allowing run time type validation

Table of Contents

Need

Problem

Parsing JSON

Javascript is not typed safe at all, you ask for a number, send a boolean and Javascript is happy

Because of that people created TypeScript which helps but only check type at compile time which is fine until you try to decerialize a json

class User {
	name: string = "";
	age: number = 0;
	fromJson(json: string): User {
		const data = JSON.parse(json);
		this.name = data.name;
		this.age = data.age;
		return this;
	}
	isAdult(): boolean {
		return this.age >= 18;
	}
}
const user = new User().fromJson('{"name": "John", "age": true}');
console.log(typeof user.age); // boolean, not number as described above

Unknown type

Appart from parsing json you can also have problems with TypeScript not always error when you won't get the type you expect

-const duration: [number|null, number|null] = [params['min'] || null, params['max'] || null];
+const duration: [number|null, number|null] = [Number(params['min']) || null, Number(params['max']) || null];

These 2 lines of code are a commit I made recently in a project, I thought undefined would be converted to null with the || operator but it is not, I kept getting undefined in the array which caused our code to make a wrong request to the backend and get empty array as response
Using Number transformed my undefined into a NaN which unlike undefined is converted to null using the || operator

Appending properties

JavaScript lets you do add any property that doesn't exist to an object, this can seem like not a big deal but it can also cause some problems

class User {
	name: string = "";
	age: number = 0;
	constructor(name: string, age: number) {
		this.name = name;
		this.age = age;
	}
}
const user = new User("John Doe", 42);
user.isMarried = true; // no error
console.log(Object.keys(user)); // ["name", "age", "isMarried"] instead of ["name", "age"] like defined in the class

Type supperposition

In javascript you can use typeof to check the type of a variable, however you probably know that any custom type will be object

typeof new Date(); // "object"
typeof null; // "object"
typeof { name: "John Doe", age: 42 }; // "object"

Both these variables are said to be of type object even though it would be reasonable to think that the first one is a Date and the second one is null

Non-numerical numbers

In javascript you have the NaN value which is a number but litterally means "not a number", you also have Infinity which isn't numerical

const infinity = 1 / 0;
const nan = 0 / 0;
console.log(infinity); // Infinity
console.log(nan); // NaN
typeof infinity; // number
typeof nan; // number

Converting types

This blew my mind when I discovered it, but while working on the same project, I wanted to write a test in which I had to mock angular's Router and I got multiple compilation errors from either TypeScript or Angular, in the end I wrote this code

class myRouter {}
function myFunction(router: Router) {}
myFunction(new myRouter() as unknown as Router);

Which is me sending a myRouter to a function which only accepts Router even though myRouter doesn't extend Router, this shouldn't be possible using a language supposedly typed safe, but TypeScript allows it

Solution

In an ideal world TypeScript would modify your code to add some type checking at runtime, however I don't think Microsoft is going to do that soon and I'm too dumb to make a pull request to a big project like TypeScript

Instead I created this library which allows you to easily add type checking at runtime, now you can at any point in your code add a validation to your variable to ensute they are using the right type

Installation

This library is available on npm, you can install it to your project using one of the following commands

npm install runTypeJs
yarn add runTypeJs
pnpm install runTypeJs

Usage

There's multiple ways to use this library, you can go from just a function returning the type of the variable (more precise than typeof) to a full class in which you can define the structure of the class and use it to validate any instance of the class and recursively validate other classes in it if they were defined.

getType

This is the most basic function, it takes a variable and returns its type.
It is more precise than typeof as it will return the name of the type instead of object for any custom type
It will also distinguish numbers from NaN and Infinity

import { getType } from "runTypeJs";

console.log(getType(new Date())); // Date
console.log(getType({ name: "John Doe", age: 42 })); // Object
console.log(getType(null)); // null
console.log(getType(42)); // number
console.log(getType(NaN)); // NaN
console.log(getType(Infinity)); // Infinity

checkType

This function takes a variable and a type or an array of types and checks if the variable is of the right type
It will throw an error if the type is not correct

import { checkType } from "runTypeJs";

checkType(42, "number"); // no error
checkType(NaN, "number"); // error
checkType(NaN, ["number", "NaN"]); // no error

checkStructure

This function takes a variable and a structure and checks if the variable is of the right structure
It will throw an error if the structure is not correct
It will also check if the variable is of the right type

import { checkStructure } from "runTypeJs";

checkStructure({ name: "John Doe", age: 42 }, { name: "string", age: "number" }); // no error
checkStructure({ name: "John Doe", age: NaN }, { name: "string", age: "number" }); // error
checkStructure({ name: "John Doe", age: NaN }, { name: "string", age: ["number", "NaN"] }); // no error
checkStructure({ name: "John Doe" }, { name: "string", age: "number" }); // error
checkStructure({ name: "John Doe", age: 42, married: true }, { name: "string", age: "number" }); // error

TypeChecker

This class is allow you to define the structure of a class once and then use it to validate any instance of the class

Defining a structure

There are 2 ways to define a structure, either you write it by hand or you use an instance of the class and let the library do it for you
Be aware that the second method will set the type of the properties to the type used in the instance, it won't know if the property can accept multiple types

import { TypeChecker } from "runTypeJs";
class User {
	name: string|[string, string] = "";
	age: number = 0;
}
new TypeChecker().define("User", { name: ["string", "Array"], age: "number" }); // define User as { name: [string, Array], age: number }
new TypeChecker().defineFromInstance(new User()); // define User as { name: string, age: number }, not knowing that name can be an array

Checking a type

You can check a type using the checkType method, unlike the checkType function, this method will check the structure of what you are passing if you defined it

import { TypeChecker } from "runTypeJs";
class User {
	name: string|[string, string] = "";
	age: number = 0;
	constructor(name: string|[string, string], age: number) {
		this.name = name;
		this.age = age;
	}
}

const typeChecker = new TypeChecker();
typeChecker.checkType(new User(["John", "Doe"], 42), "User"); // no error
typeChecker.define("User", { name: "string", age: "number" });
typeChecker.checkType(new User("John Doe", 42), "User"); // no error
typeChecker.checkType(new User(["John", "Doe"], 42), "User"); // error, expected string but got Array

Checking a structure

You can check a structure using the checkStructure method, unlike the checkStructure function, this method will check the structure of the typed stored in the class you are passing if you defined them

import { TypeChecker } from "runTypeJs";
class User {
	name: string|[string, string] = "";
	age: number = 0;
	constructor(name: string|[string, string], age: number) {
		this.name = name;
		this.age = age;
	}
}
class Dog {
	owner: User = new User("", 0);
	age: number = 0;
	constructor(owner: User, age: number) {
		this.owner = owner;
		this.age = age;
	}
}
const typeChecker = new TypeChecker();
typeChecker.defineFromInstance(new Dog());
typeChecker.checkStructure(new Dog(new User(["John", "Doe"], 42), 3)); // no error
typeChecker.define("User", { name: "string", age: "number" });
typeChecker.checkStructure(new Dog(new User(["John", "Doe"], 42), 3)); // error, expected string but got Array
typeChecker.checkStructure(new Dog(new User("John Doe", 42), 3)); // no error

Contributing

New issues

If you find a bug or have a feature request, please open an issue on the repository and I will try to answer it as soon as possible

Pull requests

If you want to contribute to the project, feel free to open a pull request for one of the existing issues, I will review it and merge it if it is good.
If you want to add a new feature, please open an issue first to discuss it with me before opening a pull request

If you do end up opening a pull request, there are some rules that you need to follow:

  • Make sure to write tests for your code, I have a pipeline that checks for them and the coverage's threshold is set to 100% so every case must be covered
  • Format the code using pnpm format so that it has the same style as the rest of the project
  • Lint the code using pnpm lint to ensure code quality, you may need in some cases to add an exception to the linter like allowing any to the getType function but don't use this if you don't have to
  • Please write your code in a clean and readable way, I will not merge your code until I am satisfied with it
  • If needed, you should write documentation for your code in the README.md file so that people using the library can understand how it works

License

This project is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License