1.0.0 • Published 3 years ago

@nullndr/tsutils v1.0.0

Weekly downloads
-
License
MIT
Repository
github
Last release
3 years ago

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";