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 🙏

© 2024 – Pkg Stats / Ryan Hefner

reflect-types

v2.0.0

Published

Type combinators for JavaScript/TypeScript at runtime

Downloads

5

Readme

Reflect Types

Reflect types allows you to work with types both at compile time and at runtime.

Think Zod, but with the useful feature of being able to analyse and traverse the types, not just use them for validation.

⚠️ This library is still under development. Things might not work or might not work as advertised. You have been warned!

Make generic functions truly generic with type information

import { types } from "reflect-types"

function buildEquality<T>(t: Type): boolean {
    switch (t.kind) {
        case 'string':
            return (a,b) => a === b;
        case 'vec2':
            return (a,b) => a[0] === b[0] && a[1] === b[1];
        // and so on ...
    }
}

function assoc<K, V>(data: Array<[K,V]>, key: K, k: Type) {
    const eq = buildEquality(k);
    // ...
}

const data = [
    [1, 'one'],
    [5, 'five'],
    [3, 'three'],
    [6, 'six'],
];

const elementType = types.vec2();

assoc(data, 1, elementType); // returns 'one'

Define an object type and validate some data with it

import { types } from "reflect-types"
import { validate } from "reflect-type/lib/validators.js"

const personType = types.object({
  id: types.uuid4(),
  fullName: types.string(),
  email: types.email(),
  dateOfBirth: types.date(),
});

const person1 = {
    id: '22ba434a-c662-4cc9-8a05-5cf1c7c90fd7',
    fullName: 'James Smith',
    email: '[email protected]',
    dateOfBirth: new Date('8/23/1997'),
}

const [errors, result] = validate(person1, personType);

if (errors.length > 0) {
    for (const error of errors) {
        console.log(error);
    }
    return;
}

// Yay! Now, `result` may e.g. be stored in the database.

Inspect a type in order to infer whether it is nullable

import { Type, types } from "reflect-types"

function isNullable(type: Type): boolean {
    switch (type.kind) {
        case 'literal':
            return type.value === null;
        case 'nullable':
            return true;
        case 'optional':
            return isNullable(type.type);
        case 'object':
        case 'array':
        case 'string':
        case 'boolean':
        case 'number':
            return false;
        default:
            assertNever(type);
    }
}

const type = fetchSomeTypeSomehow();

console.log(
  isNullable(type)
    ? `The type is nullable.`
    : `The type is not nullable.`);

Installation

Just install reflect-types using your favorite package manager, e.g.:

npm install reflect-types

Reference

Extending the type system

The type system is flexible enough to be extended with user-defined types.

Here is a code snippet that create a new type for RGB-colors.

import { TypeBase } from "reflect-types"

type RGB = [r: number, g: number, b: number];

export class RGBType implements TypeBase {

    // Give your type an unique name. Names should be lowercase and use dashes
    // when consisting of multiple words.
    readonly kind = 'rgb';

    // This resolves to the actual TypeScript type of value that is held by this type.
    __type!: RGB;

}

declare module "reflect-types" {
    interface Types { 
        rgb: RGBType,
    }
}

export function rgb(): RGBType {
    return new RGBType();
}

In the code above, we first define a TypeScript type for the values we wish to support, in this case RGB. Next, we create the actual class that will represent these values in reflect-types. Usually these have the suffix Type. They implement TypeBase, a minimal interface that every type should adhere to. The fields kind and __type indicate the tag and the TypeScript type, respectively. Next, the declare module-directive ensures that when a user specifies our new type somewhere, it is actually accepted by e.g. types.object(). Finally, we create a simple constructor for our type, making the class transparent and avoiding the use of new.

License

This project is licensed under the MIT license. See LICENSE.txt for more information.