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

@nullndr/tsutils

v1.0.0

Published

Some utilities for TypeScript

Downloads

1

Readme

TypeScript utils

This packages contains some types and function utilities for TypeScript.

  1. types

  2. functions

Types

CompErr

import type { CompErr } from "@nullndr/tsutils";

Brand

import type { Brand } from "@nullndr/tsutils";

TypeScript's type system is structural, meaning that any two types that are structurally equivalent are considered the same.

type Cat = { name: string };
type Dog = { name: string };

const petCat = (cat: Cat) => { console.log(cat.name); };
const pluto: Dog = { name: "Pluto" };
petCat(pluto); // works fine

In same case, you would like to simulate nominal typing inside TypeScript.

type Cat = { name: string };
type Dog = { name: string };

const petCat = (cat: Brand<Cat, "cat">) => { console.log(cat.name); };
const fido: Dog = { name: "fido" };
petCat(fido); // does not work

Union

import type { Union } from "@nullndr/tsutils";

This is just a wrapper for the union | operator:

let u: Union<string, number> = "Hello"; 
u = 1;

Intersetion

import type { Intersection } from "@nullndr/tsutils";

For object this is just a wrapper for the intersection & operator:

type Bar = { bar: number };

type Foo = { foo: number };

let i: Intersection<Bar, Foo> = { bar: 1, foo: 1};

For unions the type wraps Extract:


let i: Intersection<1 | 2 | 3, 2 | 3 | 4> = 2; // ok
i = 1; // error
i = 3; // ok
i = 4; // error

Head

import type { Head } from "@nullndr/tsutils";

This type extracts the head type of a list or tuple:

type Tuple = [string, boolean, number];

let h: Head<Tuple> = "Hello";

Tail

import type { Tail } from "@nullndr/tsutils";

This type extracts the tail type of a tuple:

type Tuple = [string, boolean, number];

let t: Tail<Tuple> = [true, 0];

IfAny

import type { IfAny } from "@nullndr/tsutils";

With A, B and C types, assign B is A is any, C otherwise.

let a: IfAny<any, number, string> = 1;
let b: IfAny<number, number, string> = "Hello";

IsAny

import type { IsAny } from "@nullndr/tsutils";

Like IfAny but returns true if the type is any, false otherwise, usefull inside other types.

XOR

import type { XOR } from "@nullndr/tsutils";

TypeScript's type system is structural, meaning that any two types that are structurally equivalent are considered the same.

This can lead to some unpleasant cases:

type A = {
    a: 1;
};

type B = {
    b: 2;
};

type C = A | B;

let a: C = { a: 1, b: 2 }; // works fine

This because { a: 1, b: 2} can be assigned both at A and B, in order to get really mutually exclusive use XOR:

type A = {
    a: 1;
};

type B = {
    b: 2;
};

let a: XOR<A, B> = { a: 1, b: 2 }; // error
a = { a: 1 }; // ok
a = { b: 2 }; // ok

ToUnion

import type { ToUnion } from "@nullndr/tsutils";

With an array, this type extracts the array's type:

let s: ToUnion<string[]> = "Hello";

With a tuple, ToUnion creates an union with each element type inside the tuple:

let s: ToUnion<[string, number, boolean]> = "Hello"; // string | number | boolean
s = 1;
s = true;

ToArray

import type { ToArray } from "@nullndr/tsutils";

This type creates an array type from a given type:

let a: ToArray<number> = [0, 1, 2, 3, 4];

Its behavior is the opposit of Flat<T>.

RemovePropsOf

import type { RemovePropsOf } from "@nullndr/tsutils";

This type removes from an object all properties that are of a specific type.

type Foo = {
    foo: number;
    foobar: number;
    bar: string;
}

let r: RemovePropsOf<Foo, number> = { bar: "Hello" };

Overwrite

import type { Overwrite } from "@nullndr/tsutils";

This type overwrites all properties of an source object which exist in a target object with the properties in the target object.

type Foo = {
    foo: number;
    bar: string;
}

type Bar = {
    foo: string;
}

let o: Overwrite<Foo, Bar> = { foo: "Hello", bar: "World" };

Difference

import type { Difference } from "@nullndr/tsutils";

AwaitedReturnType

import type { AwaitedReturnType } from "@nullndr/tsutils";

This type unwraps the awaited type of the return type of a function type.

async function foo(): Promise<number>;

let a: AwaitedReturnType<typeof foo> = 2;

Filter

import type { Filter } from "@nullndr/tsutils";

Flat

import type { Flat } from "@nullndr/tsutils";

This type flats an array.

let f: Flat<string[]> = "Hello";

Its behavior is the opposit of ToArray<T>

DeepFlat

import type { DeepFlat } from "@nullndr/tsutils";

Like Flat<T> but recursively flats the result.

let f: DeepFlat<string[][][][]> = "Hello";

Values

import type { Values } from "@nullndr/tsutils";

Retrives a union of all property values in an object.

type Foo = {
    a: string;
    b: 1;
    c: 2;
};

let v: Values<Foo> = "Hello"; // Ok
v = 1; // ok
v = 2; // ok
v = 3; // error

SimmetricDifference

import type { SimmetricDifference } from "@nullndr/tsutils";

This type extracts the simmetric difference of two objects.

type Foo = {
    foo: number;
    foobar: string;
};

type Bar = {
    bar: number;
    foobar: string;
};

let s: SimmetricDifference<Foo, Bar> = { foo: 1, bar: 1};

To get the simmetric difference of two unions, you can use Exclude<T, U> united with Exclude<U, T>.

type Foo = 1 | 2 | 3 

type Bar = 2 | 4

type S = Exclude<Foo, Bar> | Exclude<Bar, Foo>

let a: S = 1; // ok
a = 2; // error
a = 3; // ok
a = 4; // ok

Functions

assertDefined

import { assertDefined } from "@nullndr/tsutils";

This function asserts that a given value is not null or undefined.

const user: User | null = await findUser(id);

assertDefined(user);

console.log(user.firstName);

The function throws an 'AssertFailerror if the value isnullorundefined`.

assertNever

import { assertNever } from "@nullndr/tsutils";

assert

import { assert } from "@nullndr/tsutils";