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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@igorskyflyer/unite

v1.1.0

Published

Zero-dependency TypeScript library for deriving a union type, a type guard, and an array validator from a single source array.

Downloads

23

Readme

Table of Contents

Features

  • ✅ Generates a literal union type from one array, no as const required
  • 🛡️ Runtime validator included, checks values against the exact same source array
  • 📦 One declaration powers the type, the guard and the raw values list
  • 🔒 Compile-time error blocks widened string[] inputs before they cause bugs
  • 🧊 Source array frozen internally, prevents accidental mutation after creation
  • 🔍 Array validator built in, checks whole lists against the allowed set
  • 🪶 Zero dependencies, tiny footprint
  • 🎯 Full TypeScript autocomplete on valid values
  • ⚡ Negligible runtime cost, validation stays as fast as a plain includes() check
  • 🧩 Fits any project needing a single source of truth for allowed string values

Usage

Install it by executing any of the following, depending on the preferred package manager:

bun add @igorskyflyer/unite
pnpm add @igorskyflyer/unite
yarn add @igorskyflyer/unite
npm i @igorskyflyer/unite

API

union(allowedValues)

function union<const T extends readonly string[]>(allowedValues: T): UnionValidator<T>

Derives a literal union type and a matching runtime validator from a single array of allowed string values.

The array should be passed as a literal, or as a value typed with as const, so that TypeScript can infer its literal element types rather than widening them to string. Passing a variable explicitly typed as string[] is rejected at compile time.

UnionValidator<T>

interface UnionValidator<T extends readonly string[]>

The interface returned by union(). Exported to allow explicit type annotations on exported variables when isolatedDeclarations is enabled in project's tsconfig.json.

.isValid(value)

isValid(value: unknown): value is T[number]

Checks whether a single value belongs to the allowed set.

Acts as a TypeScript type guard: when it returns true, value is narrowed to the literal union type derived from the allowed values.

.isValidArray(value)

isValidArray(value: unknown): value is T[number][]

Checks whether every element of an array belongs to the allowed set.

Acts as a TypeScript type guard: when it returns true, value is narrowed to an array of the literal union type derived from the allowed values. Returns false if value is not an array. Returns true for an empty array.

.values

readonly values: T

The original array of allowed values, frozen and returned as-is.

Mutating the array originally passed to union() has no effect on this property or on the validator's behavior.

ExtractUnion<T>

type ExtractUnion<T extends { _type: unknown }> = T['_type']

Extracts the literal union type from a UnionValidator<T> instance returned by union().

Examples

Basic Usage

import { union, type ExtractUnion } from '@igorskyflyer/unite'

const resourceType = union(['script', 'style'])
type ResourceType = ExtractUnion<typeof resourceType>
// "script" | "style"

resourceType.isValid('script')
// true

resourceType.isValid('link')
// false

resourceType.isValidArray(['script', 'style'])
// true

resourceType.values
// readonly ["script", "style"]

Type Narrowing

// Narrowing unknown input, e.g. parsed JSON or a config value.

function handle(input: unknown) {
  if (resourceType.isValid(input)) {
    // input: "script" | "style" here, not string
  }
}

Usage with --isolatedDeclarations

import { union, type UnionValidator } from '@igorskyflyer/unite'

const allowed = ['script', 'style'] as const

export const resourceType: UnionValidator<typeof allowed> = union(allowed)
// usage when `isolatedDeclarations` is enabled in project's TSConfig

Implementation

union() uses a const type parameter to infer the literal union directly from the array passed in, without requiring as const. A conditional type rejects, at compile time, any input whose element type has already widened to string, for example, a variable declared as string[] before being passed in.

The original array is copied and frozen internally before being returned via .values, so mutating the caller's original array after the validator is created has no effect on the validator's behavior.

.isValid() and .isValidArray() perform the actual runtime check, using Array.prototype.includes and Array.prototype.every respectively against the frozen array. No property named _type exists on the returned object at runtime; it is declared only in the TypeScript interface, for ExtractUnion to read at the type level.

Motivation

Deriving a literal union type and a matching runtime validator from the same array is a common requirement, usually solved by hand with as const plus a separately written type guard. This pattern is prone to drift: the array, the type, and the guard can fall out of sync without a compile error, particularly when the array is declared with an explicit string[] annotation instead of a literal.

unite collapses this into a single declaration, so the type, the guard, and the original values all derive from one source array.

Changelog

Read about the latest changes in the CHANGELOG.

License

Licensed under the MIT license.

Support

Related

@igorskyflyer/rawelement

A utility that lets you manipulate HTML elements, their attributes and innerHTML as strings, on the go and then render the modified HTML. Very useful in SSG projects.

@igorskyflyer/common-types

🔦 Provides frequently used types for your TypeScript projects. 🦄

@igorskyflyer/common-color

🎨 Provides common Color-related TypeScript types. 🌈

@igorskyflyer/valid-path

🧰 Determines whether a given value can be a valid file/directory name. 🏜

@igorskyflyer/vscode-folderpicker

✨ Fast, custom cross-platform folder picker and creator for VS Code with icons, validation, and instant navigation. 🎨

Author

Created by Igor Dimitrijević (igorskyflyer), a senior full-stack software engineer and freelance architect.