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

@sygn/types

v1.1.1

Published

Type checking utilities — is*, not*, has*, all*, getFirst*, force* for every JS type, plus typeOf, intoArray and instanceOf

Readme

@sygn/types

🧬 The modern successor to types.js — a zero-dependency ESM + TypeScript rewrite. The type-checking API is compatible (is / not / has / all / getFirst, plus typeOf, intoArray, *StringOrNumber); force* is redesigned (no auto-conversion) and the legacy enum and logging helpers are dropped for good.

Tiny, fast, dynamic type checking for JavaScript and TypeScript. Every JS type gets six forms — is, not, has, all, getFirst, force — shipped as tree-shakeable ES modules with first-class TypeScript type guards.

Why

Static types vanish at runtime. @sygn/types lets you assert and enforce types on real values as your app runs — safely handling null, NaN, boxed primitives, and the other awkward corners of JavaScript — so a bad value becomes a handled case instead of a crash.

  • Six forms per type: is[Type], not[Type], has[Type], all[Type], getFirst[Type], force[Type]
  • Check many values at once with has / all, or pick one with getFirst
  • force a guaranteed return type — the value, a valid replacement, or a type literal
  • Real TypeScript type guardsis[Type] narrows in if blocks
  • Extras: typeOf, intoArray, instanceOf, and *StringOrNumber checks
  • Zero dependencies, ESM, importable per type or per function

Install

npm install @sygn/types

Usage

Import from the package root, or from a per-type / per-function subpath so bundlers only pull in what you use:

// everything from the barrel
import { isString, allNumber, forceArray } from '@sygn/types';

// just one type's five forms
import { isString, notString, hasString, allString, forceString } from '@sygn/types/string';

// a single function
import { isString } from '@sygn/types/isString';

Browser (global)

No build step or bundler? Load the prebuilt bundle with a plain <script> and it binds a global Types:

<script src="https://cdn.jsdelivr.net/npm/@sygn/types"></script>
<script>
	Types.isString( 'hi' );        // true
	Types.forceNumber( 'x', 0 );   // 0
	Types.instanceOf( [], Array ); // true
</script>

Types is a flat object holding every is / not / has / all / getFirst / force function plus typeOf (and Types.typeof), intoArray, instanceOf, notInstanceOf, the *StringOrNumber checks, and createForce — e.g. Types.isArray, Types.getFirstString, Types.typeOf( x ).

The six forms

is[Type]( value ) and not[Type]( value ) — single-value checks.

isString( 'hello' );      // true
isString( 23456 );        // false
isBoolean( false );       // true
isArray( [ 1, 2, 3 ] );   // true
isObject( [ 1, 2, 3 ] );  // false
isObject( /re/g );        // false
isObject( { a: 1 } );     // true
isNaN( Number( 'x' ) );   // true

notNull( '' );            // true
notUndefined( undefined );// false
isDefined( null );        // true  (only `undefined` is "not defined")
isDefined( undefined );   // false

all[Type]( ...values )true when every argument is of the type.

allString( '', ' ', 'text' );                 // true
allString( '', ' ', 'text', 123 );            // false
allArray( [ 1, 2 ], [ {} ], [ false, true ] );// true
allArray( [ 1, 2 ], [ {} ], /re/ );           // false

has[Type]( ...values )true when at least one argument is of the type.

hasString( 123, { v: 1 }, [ '?' ] );          // false
hasFunction( 123, {}, () => {} );             // true
hasUndefined( 'x', 123, null );               // false
hasUndefined( 'x', 123, undefined );          // true

Note: all[Type]() with no arguments is true (vacuously), and has[Type]() with no arguments is false — they follow Array.prototype.every / .some.

getFirst[Type]( ...values ) — the first argument of the type, else undefined.

getFirstString( 1, 'a', 'b' );    // 'a'
getFirstNumber( 'x', {}, 5 );     // 5
getFirstArray( 1, [ 9 ], [ 2 ] ); // [ 9 ]
getFirstString( 1, 2 );           // undefined

force[Type]( value, ...replacements ) — always returns a value of the type. It returns value if it matches, otherwise the first replacement that matches, otherwise a literal of that type. No coercion happens — a value either is the type or it doesn't count.

forceString( undefined );        // ''            (type literal)
forceString( null, 'ok' );       // 'ok'          (replacement matches)
forceString( 33 );               // ''            (33 is not a string — not converted)
forceString( 33, 'fallback' );   // 'fallback'

forceNumber( '35px' );           // 0             (not parsed; type literal)
forceNumber( '35px', 42 );       // 42
forceArray( 'text' );            // []
forceArray( 'text', [ 1, 2 ] );  // [ 1, 2 ]

Because forceFunction always returns something callable, you can guard calls in one line without crashing:

const log = null;

forceFunction( log, console.log )( 'safe!' );  // logs 'safe!' (replacement used)
forceFunction( log, null )( 'nothing' );       // no-op — returns the empty () => {} literal

instanceOf

For arbitrary constructors, instanceOf / notInstanceOf take one or more classes and check them all:

import { instanceOf, notInstanceOf } from '@sygn/types/instanceOf';

instanceOf( new Date(), Date );          // true
instanceOf( x, Date, Object );           // true only if x is an instance of every class
notInstanceOf( 'plain', Date, RegExp );  // true

More helpers

typeOf( value ) — a reliable, lowercase type name (a saner typeof). Matches types.js for the shared types and extends to the modern ones:

typeOf( [] );            // 'array'
typeOf( null );          // 'null'
typeOf( Number( 'x' ) ); // 'nan'
typeOf( /re/ );          // 'regexp'
typeOf( new Map() );     // 'map'
typeOf( 5n );            // 'bigint'

intoArray( ...values ) — normalize arguments, or a space-delimited string, into an array:

intoArray( '1 2 3' );  // [ '1', '2', '3' ]
intoArray( 'a', 'b' ); // [ 'a', 'b' ]
intoArray( [ 1, 2 ] ); // [ 1, 2 ]

*StringOrNumber — the is / not / has / all / getFirst forms for the "string or number" union:

isStringOrNumber( 5 );           // true
allStringOrNumber( 'a', 1 );     // true
getFirstStringOrNumber( {}, 3 ); // 3

TypeScript

Every is[Type] is a type guard, so it narrows inside conditionals:

function greet( value: unknown ) {
	if ( isString( value ) ) {
		return value.toUpperCase(); // value is `string` here
	}

	return forceString( value ); // always a `string`
}

createForce

force[Type] is built on createForce, which you can use to make your own enforcers for any predicate:

import createForce from '@sygn/types/createForce';
import { isString } from '@sygn/types/string';

const forceUpper = createForce( isString, s => s.toUpperCase(), '' );

forceUpper( 'hi' );        // 'HI'
forceUpper( 42 );          // ''     (no match, no replacement -> literal)
forceUpper( 42, 'ok' );    // 'OK'   (replacement matches, then transformed)

Auto-converting force

force* never coerces — a value is the type or it isn't. If you want the old types.js auto-convert behaviour (e.g. '35px' → 35), build it explicitly with createForce. Coercion stays opt-in and local, instead of a global flag:

import { isNumber } from '@sygn/types/number';

const toNumber = createForce(
	v => isNumber( v ) || ( isString( v ) && Number.isInteger( parseInt( v, 10 ) ) ),
	v => isString( v ) ? parseInt( v, 10 ) : v,
	0
);

toNumber( '35px' );    // 35
toNumber( 'abc' );     // 0   (not convertible -> literal)
toNumber( 'abc', 12 ); // 12  (replacement)

Supported types

Each type below exposes is / not / has / all / getFirst / force. Import it as @sygn/types/<name>.

| Name | is narrows to (TS) | force fallback | | --------------- | ---------------------------------- | ----------------------- | | array | unknown[] | [] | | arrowFunction | ( ...args: unknown[] ) => unknown| () => {} | | bigint | bigint | 0n | | boolean | boolean | false | | date | Date | new Date( 0 ) | | defined | T (from T \| undefined) | null | | error | Error | new Error() | | function | ( ...args: unknown[] ) => unknown| () => {} | | map | Map<unknown, unknown> | new Map() | | nan | number (an actual NaN) | NaN | | null | null | null | | number | number | 0 | | object | Record<string, unknown> | {} | | promise | Promise<unknown> | Promise.resolve() | | regExp | RegExp | /(?:)/ | | set | Set<unknown> | new Set() | | string | string | '' | | symbol | symbol | Symbol( 'default' ) | | undefined | undefined | undefined | | url | URL | new URL( 'about:blank' ) | | weakMap | WeakMap<object, unknown> | new WeakMap() | | weakSet | WeakSet<object> | new WeakSet() |

Plus instanceOf / notInstanceOf (see above).

License

ISC © SYGN — Dennis van der Sluis