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

typeprops

v0.2.0

Published

Small library for describing HKTs in TypeScript

Downloads

2

Readme

TypeProps

Join the chat at https://gitter.im/TypeProps/Lobby

Small library for describing HKTs in TypeScript

How can you help?

This library is still in alpha mode, expect breaking changes for now. What's currently needed is lots of interaction with people trying to type complex examples. Feel free to join us at Gitter or to post issues on the repository with sample code.

How you use it

This repository contains a lot of examples to show you how things work. Unfortunately, for usability purposes, the library is a little lenient in some places and too strict in others, so there's a razor thin edge when defining overly abstract types (like, say, a Monad HKT). Write lots of tests to make sure the type you wrote is behaving correctly. TypeProps tends to handle quite nicely for exactly the right type, even offering very good inference and assignment, but sometimes it requires some gentle love to get there.

How it works

Playground: Proof of concept

This library uses a type-level pattern matcher to match types against a "type dictionary". The type dictionary contains types I call "TypeProps", which describe two things:

  • Can I infer parameters for this type?
  • Given another type, how do I construct a new type?

Here's the base type dictionary, which defines what do with arrays, null, undefined and the generic case:

interface TypeProps<T = {}, Params extends ArrayLike<any> = never> {
    array: {
        infer: T extends Array<infer A> ? [A] : never;
        construct: Params[0][];
    };
    null: {
        infer: null extends T ? [never] : never;
        construct: null;
    };
    undefined: {
        infer: undefined extends T ? [never] : never;
        construct: undefined;
    };
    unfound: {
        infer: [NonNullable<T>];
        construct: Params[0];
    };
}

Using "declaration merging", you can add more types to this dictionary, and the library also supports adding secondary dictionaries, to express things like Functor (Either e) a in Haskell (functor only has one type parameter, Either has two, a secondary mapping is needed).

What's with the weird null, undefined and unfound cases?

These were put in to support abstracting nullables as a Monad. The follow code demonstrates that:

const nullableFunctor: StaticFunctor<object | null | undefined> = {
    map: <A, B>(
        fn: (a: A) => B,
        fa: A | null | undefined
    ): B | null | undefined => {
        return fa != undefined ? fn(fa) : fa;
    }
};

This is a very powerful idea, but be careful exposing it to other libraries that expect Static-land compliance. As far as I can tell, this function is not compliant with that spec. I might need to pull the feature out in the future if day-to-day use shows that it makes other types incorrect, but for now I haven't found such cases.