Home

Awesome

ts-types-utils

npm version Conventional Commits code style: prettier

Type utilities for typescript

Table of Contents

Usage

npm i -D ts-type-utils
import * as TsTypeUtils from "ts-type-utils";

Match

Match<T, M, F> // T is object, M is what to match to, F negate

Pick from T all properties that match M, or not match M if F is false

import { Match } from "ts-types-utils";

type FunctionProperties<T> = Match<T, Function>; // Match<T, Function, true>
type NonFunctionProperties<T> = Match<T, Function, false>;

type Foo = {
  a: string;
  b: number;
  c: () => void;
  d: (hello: string) => number;
};

const nonfuncs: NonFunctionProperties<Foo>; // { a: string, b: number }
const funcs: FunctionProperties<Foo>; // { c: () => void; d: (hello: string) => number }

MatchNames

MatchNames<T, M, F> // T is object, M is what to match to, F negate

Get properties names from T that match M, or not match M if F is false

import { MatchNames } from "ts-types-utils";

type FunctionPropertiesNames<T> = MatchNames<T, Function>; // MatchNames<T, Function, true>
type NonFunctionPropertiesNames<T> = MatchNames<T, Function, false>;

type Foo = {
  a: string;
  b: number;
  c: () => void;
  d: (hello: string) => number;
};

const nonfuncs: NonFunctionPropertiesNames<Foo>; // "a" | "b"
const funcs: FunctionPropertiesNames<Foo>; // "c" | "d"

Assign

Assign<A, B> like A & B but replaces intersected A types with the ones from B

import { Assign } from "ts-types-utils";

type A = {
  foo: string;
  bar: number;
};
type B = {
  foo: number;
  baz: boolean;
};

const bad: A & B = {
  foo: 1, // error type string | number doesn't match number
  bar: 2,
  baz: false
};
const good: Assign<A, B> = {
  foo: 1,
  bar: 2,
  baz: false
};

Func

Func<P, R> // P: params type, R: return type

This doesn't really bring much but syntactic sugar

import { Func } from "ts-types-utils";

const myfunc: Func<[string, number], boolean>; // (a: string, b: number) => boolean

PromiseOr

PromiseOr<T> = T | Promise<T>

Why? Because it gets cumbersome having to repeat long types again and again. I've found myself using this a lot, specially in interfaces (for greater flexibility).

export function test(): Promise<string> | string { ... }

Can be simplified to

export function test(): PromiseOr<string> { ... }

Action

Action<T = void> = () => Action

Why? Because it gets tiring and makes the code less clear having to write function types.

export function invoke(callback: () => string)): void { ... }

export function invoke(callback: () => string | number | object)): void { ... }

export function invoke(callback: () => boolean | object)): () => boolean | string { ... }

Can be simplified to

export function invoke(callback: Action<string>)): void { ... }

export function invoke(callback: Action<string | number | object>): void { ... }

export function invoke(callback: Action<boolean | object>):  Action<boolean | string> { ...

UndefinedToOptional

UndefinedToOptional<T>
import { UndefinedToOptional } from "ts-types-utils";

interface Options {
  times: number | undefined
}
function foo(options: Options) {}
foo({}) // Error expected times

function bar(options: UndefinedToOptional<Options>) {}
bar({}) // Good: times is optional now

UndefinedToOptional<Options> // { times?: number }

ArgsType ( DEPRECATED: already in std types as Parameters<T> )

ArgsType<F> // F is function

Like built-in ReturnType but for the args of a function, works for any number of arguments

import { ArgsType } from "ts-types-utils";
function myFunc(a: string, b: number) {}
const all: ArgsType<typeof myFunc>; // [string, number]
const first: ArgsType<typeof myFunc>[0]; // string
const second: ArgsType<typeof myFunc>[1]; // number

Related

Tests were made with typescript-test-utils

Contributors