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

@danwithabox/nullish

v0.1.1

Published

Utilities that pair well with the lovely nullish coalescing (??) operator

Readme

@danwithabox/nullish

Utilities that pair well with the lovely nullish coalescing (??) operator.

License

Install

$ npm install @danwithabox/nullish --save

Overview

The provided utilities are:

nullishMap(value, mapFn)

import { nullishMap } from "@danwithabox/nullish";

// Instead of expecting unsafe data,
type Data = { foo: number, bar: number, } /* | null | undefined */;

// define operations on safe data,
function processSafeData(data: Data): number {
    return data.foo + data.bar;
}
// then bridge the safety gap with `nullishMap()`
function handleUnsafeData(unsafeData: Data | null | undefined): number {
    return nullishMap(unsafeData, processSafeData) ?? 0;
}

// or use it in any other way to make more concise code
function greet(data?: { name: string, surname: string, } | null): string {
    return nullishMap(data, data => `Hello, ${data.name} ${data.surname}!`) ?? `Hi there!`;
    // Note the lack of branches and optional chaining (?.) operators, it's just one succinct line
}

console.log(greet({ name: `Daniel`, surname: `Withabox`, }));
// Hello, Daniel Withabox!

console.log(greet());
// Hi there!

Map a nullish value as if it were non-nullish.

The result retains either null, or undefined, or both, or neither, depending on what's inferred from the input value.

Practically, the possible mappings are:

  • T | null | undefined => R | null | undefined

    const val = 0 as number | null | undefined;
    const res = nullishMap(val, val => `${val}`);
    //    ^ string | null | undefined
  • T | undefined => R | undefined

    const val = 0 as number | undefined;
    const res = nullishMap(val, val => `${val}`);
    //    ^ string | undefined
  • T | null => R | null

    const val = 0 as number | null;
    const res = nullishMap(val, val => `${val}`);
    //    ^ string | null
  • T => R (not terribly useful, but it's allowed for simplicity's sake)

    const val = 0 as number;
    const res = nullishMap(val, val => `${val}`);
    //    ^ string

nullishOf(value)

import { nullishMap, nullishOf } from "@danwithabox/nullish";

// Optional value declaration: the type is inferred and made optional without any manual typing
let complicatedDeclaration = nullishOf({
    foo: 1,
    bar: { baz: 2, },
});

function calculate(): number {
    // Handle the value as if it weren't optional
    return nullishMap(complicatedDeclaration, _ => _.foo + _.bar.baz) ?? 0;
}

console.log(calculate());
// 3

complicatedDeclaration = null; // assignment does not cause a type error
console.log(calculate());
// 0

Augment a value's type with null and undefined.

Zero performance impact at runtime, as it is simply an identity function, and it most likely gets inlined.

Useful in a few common situations:

  • Making an inferred type optional at variable declaration, since something like https://github.com/microsoft/TypeScript/issues/13321 is not yet possible:

    let optional = nullishOf({ foo: 1, bar: 2, }) ?? void 0;
    //  ^ { foo: number; bar: number; } | undefined
  • Safely accessing arrays without enabling noUncheckedIndexedAccess in tsconfig.json:

    const myArray = [0, , 2].map(n => Boolean(n));
    
    // Without `noUncheckedIndexedAccess`:
    let element = myArray[1];
    //  ^ `boolean`
    //    this is incorrect, due to the empty element
    
    // With manual typing:
    let maybeElement1 = myArray[1] as undefined | (typeof myArray)[number];
    //  ^ `boolean | undefined`
    //    correct, but a hassle to type
    
    // With `nullishOf`:
    let maybeElement2 = nullishOf(myArray[1]);
    //  ^ `boolean | null | undefined`
    //    correct enough: it has an extraneous `null`, but that's fine in most   situations
    
    // And if you want to narrow to either `null` or `undefined`:
    let maybeElement3 = nullishOf(myArray[1]) ?? null;
    //  ^ `boolean | null`
    //     correct
    
    let maybeElement4 = nullishOf(myArray[1]) ?? void 0;
    //  ^ `boolean | undefined`
    //     correct

Acknowledgements

Motivation to release this, and a realization that not only I needed such a thing, came from: