npm.io
2.0.2 • Published 1 week ago

strong-type

Licence
MIT
Version
2.0.2
Deps
0
Size
1.5 MB
Vulns
0
Weekly
0
Stars
8

strong-type JavaScript values passing through a native type-validation gate

strong-type

Overview · Validator reference · Tests & coverage · Playground

npm version Node support CI license runtime dependencies

Native type enforcement for JavaScript. strong-type runs as the same untransformed ES module in browsers and Node. Strict checks throw a useful TypeError; non-strict checks return a boolean.

Native by design

Property Guarantee What it means
Module format Native ESM The checked-in JavaScript is what the runtime executes.
Runtime dependencies None No third-party production packages.
Development dependencies vanilla-test 2.1.0 The exact test-runner pin is development-only; runtime installs remain dependency-free.
Bundler Not required Browser and Node imports work directly.
Transpiler Not required No generated CommonJS or compatibility copy.
Default entry point Isomorphic index.js contains no node:* imports.
Node support Explicit adapter strong-type/node adds Node-only precision checks.
Extensibility Exported Is class Custom validators work directly and in unions.

Install

npm install strong-type
Import Runtime Contents Build required
strong-type Browser + Node All isomorphic and guarded host validators No
strong-type/index.js Browser + Node Compatibility path to the same core No
strong-type/node Node Core plus Node built-ins and exact util.types checks No
strong-type/node.js Node Compatibility path to the Node adapter No

Quick start

import Is from 'strong-type';

const is=new Is;
const weakIs=new Is(false);

is.string('strong-type');        // true
weakIs.number('42');             // false
is.union(new Map,'map|set');     // true

is.number('42');                 // throws TypeError

Strict and non-strict modes

Mode Create Passing check Failing check Best use
Strict new Is or new Is(true) Returns true Throws TypeError Contracts and enforcement
Non-strict new Is(false) Returns true Returns false Branching and type discovery

Every advertised method exists in every runtime. When a guarded platform capability is unavailable, strict mode throws TypeError and non-strict mode returns false. Missing APIs never leak a ReferenceError.

Validator reference

The default isomorphic entry exposes 183 validators. The Node adapter adds 18, for 201 documented validators total. The website reference gives every method its own searchable row with an example, edge case, and runtime label.

Values, primitives, and numbers
Methods What passes Important detail
defined, any, exists Anything except undefined null is defined.
null Exactly null No loose comparison; undefined fails.
nullish null or undefined Other falsy values fail.
undefined Exactly undefined null fails.
boolean Primitive booleans Boxed Boolean objects fail.
bigInt, bigint Primitive bigint values bigint is the lowercase alias.
number Primitive numbers Includes NaN and infinities.
finite, finiteNumber Finite primitive numbers Strings, null, and BigInt are not coerced.
integer Integer primitive numbers NaN and infinities fail.
safeInteger Safe integer primitive numbers Uses Number.isSafeInteger.
NaN, nan Exactly numeric NaN No string coercion.
infinity, positiveInfinity Exactly positive Infinity infinity keeps its positive-only compatibility meaning.
negativeInfinity Exactly negative Infinity Positive Infinity fails.
infinite Either infinity Finite numbers fail.
negativeZero Exactly -0 Uses Object.is; +0 fails.
string Primitive strings Boxed String objects fail.
symbol Primitive symbols Boxed Symbol objects fail.
primitive null or any non-object, non-function value Boxed primitives and functions fail.
globalThis Exactly the current globalThis Host aliases are not substituted.
atomics, json, math, reflect Their exact global namespaces Identity checks, not lookalike objects.
rawJSON Values created by JSON.rawJSON Guarded until JSON.isRawJSON exists.
Objects and collections
Methods What passes Important detail
array Arrays from any realm Uses Array.isArray.
date Date objects from any realm Invalid dates still pass.
validDate Dates with a valid time value Invalid Date fails.
map, weakMap, set, weakSet Their matching collection brands Native internal-slot probes work across realms.
object Values where typeof value === 'object' Compatibility behavior: null passes.
nonNullObject Non-null object values Use this for the ordinary meaning of object.
plainObject Plain records, including null-prototype records Arrays and class instances fail.
nullPrototypeObject Objects with an exact null prototype Ordinary object literals fail.
argumentsObject Function arguments objects Arrays fail.
promise Promise instances in the current realm Structural thenables have a separate check.
thenable Objects or functions with a callable then It never invokes then.
regExp, regexp RegExp objects from any realm regexp is the lowercase-p alias.
Boxed primitives
Method What passes Primitive near miss
boxedPrimitive Any boxed Boolean, Number, BigInt, String, or Symbol 1
booleanObject Object(true) true
numberObject Object(1) 1
bigIntObject Object(1n) 1n
stringObject Object('type') 'type'
symbolObject Object(Symbol('type')) Symbol('type')
Functions and protocols
Methods What passes Important detail
function, callable Anything whose typeof is function Includes async and generator functions.
asyncFunction Async functions Ordinary functions fail.
generatorFunction Generator functions Generator objects use generator.
asyncGeneratorFunction Async generator functions Objects use asyncGenerator.
generator, asyncGenerator Their matching generator iterator objects Function values fail.
iterator Values with a callable next Structural by design.
asyncIterator Values with next and Symbol.asyncIterator Structural by design.
iterable, asyncIterable Values with the matching symbol method Null-safe and getter-safe.
Errors
Methods What passes Runtime
error Error instances Shared
aggregateError AggregateError instances Guarded standard
evalError EvalError instances Shared
rangeError RangeError instances Shared
referenceError ReferenceError instances Shared
syntaxError SyntaxError instances Shared
typeError TypeError instances Shared
URIError, uriError URIError instances Shared; lowercase alias included
suppressedError SuppressedError instances Guarded standard
Typed arrays and buffers
Methods What passes Important detail
typedArray Any typed array Excludes DataView.
arrayBufferView Any typed array or DataView Uses ArrayBuffer.isView.
bigInt64Array, bigUint64Array Matching BigInt typed arrays Exact brand.
float16Array Float16Array Guarded on older runtimes.
float32Array, float64Array Matching float typed arrays Exact brand.
int8Array, int16Array, int32Array Matching signed integer typed arrays Exact brand.
uint8Array, uint8ClampedArray, uint16Array, uint32Array Matching unsigned integer typed arrays A Node Buffer is also a Uint8Array.
arrayBuffer ArrayBuffer Cross-realm native slot probe.
sharedArrayBuffer SharedArrayBuffer Guarded where shared memory is absent.
anyArrayBuffer Either buffer kind Views fail.
dataView DataView Typed arrays fail.
resizableArrayBuffer Resizable ArrayBuffer values Fixed buffers fail.
growableSharedArrayBuffer Growable SharedArrayBuffer values Fixed shared buffers fail.
detachedArrayBuffer Transferred/detached ArrayBuffer values The fallback probe is non-destructive.
Intl
Methods What passes Availability
intlDateTimeFormat Intl.DateTimeFormat Shared
intlCollator Intl.Collator Shared
intlDisplayNames Intl.DisplayNames Guarded
intlListFormat Intl.ListFormat Guarded
intlLocale Intl.Locale Shared
intlNumberFormat Intl.NumberFormat Shared
intlPluralRules Intl.PluralRules Shared
intlRelativeTimeFormat Intl.RelativeTimeFormat Guarded
intlSegmenter Intl.Segmenter Guarded
intlSegments Values returned by segmenter.segment() Guarded
intlDurationFormat Intl.DurationFormat Guarded
Lifetime, resources, and Temporal
Methods What passes Availability
finalizationRegistry FinalizationRegistry objects Guarded standard
weakRef WeakRef objects Guarded standard
disposable Values with callable Symbol.dispose Guarded structural protocol
asyncDisposable Values with callable Symbol.asyncDispose Guarded structural protocol
disposableStack DisposableStack objects Guarded standard
asyncDisposableStack AsyncDisposableStack objects Guarded standard
temporalDuration Temporal.Duration Guarded standard
temporalInstant Temporal.Instant Guarded standard
temporalPlainDate Temporal.PlainDate Guarded standard
temporalPlainDateTime Temporal.PlainDateTime Guarded standard
temporalPlainMonthDay Temporal.PlainMonthDay Guarded standard
temporalPlainTime Temporal.PlainTime Guarded standard
temporalPlainYearMonth Temporal.PlainYearMonth Guarded standard
temporalZonedDateTime Temporal.ZonedDateTime Guarded standard
Shared Web APIs

These methods are present on every Is instance. The constructor or singleton is resolved through globalThis only when the method is called.

Family Methods What passes
URL url, urlSearchParams, urlPattern Matching URL API objects
Text textEncoder, textDecoder, textEncoderStream, textDecoderStream Encoding API objects
Data domException, blob, file, formData, headers, request, response Matching Fetch/data objects
Cancellation abortController, abortSignal Matching cancellation objects
Events event, eventTarget, customEvent, messageEvent, closeEvent, errorEvent Matching event objects
Messaging broadcastChannel, messageChannel, messagePort, webSocket, eventSource Matching communication objects
Host values navigator, storage The current navigator or a Storage object
Readable streams readableStream, readableStreamDefaultReader, readableStreamBYOBReader, readableStreamDefaultController, readableByteStreamController, readableStreamBYOBRequest Matching Web Streams objects
Writable streams writableStream, writableStreamDefaultWriter, writableStreamDefaultController Matching Web Streams objects
Transform streams transformStream, transformStreamDefaultController Matching transform objects
Queuing byteLengthQueuingStrategy, countQueuingStrategy Matching strategy objects
Compression compressionStream, decompressionStream Matching compression objects
Crypto crypto, subtleCrypto, cryptoKey Current crypto services and keys
Performance performance, performanceEntry, performanceMark, performanceMeasure, performanceObserver, performanceObserverEntryList, performanceResourceTiming Matching performance objects
WebAssembly webAssemblyModule, webAssemblyInstance, webAssemblyMemory, webAssemblyTable, webAssemblyGlobal, webAssemblyTag, webAssemblyException, webAssemblyCompileError, webAssemblyLinkError, webAssemblyRuntimeError Matching WebAssembly objects and errors

Core and extension methods

Method Result Purpose
throw(valueType,expectedType) false or throws Central strict/non-strict failure behavior.
check(value,pass,expectedType) true, false, or throws Turn a predicate into strong-type behavior.
typeCheck(value,type) true, false, or throws Validate a typeof result.
instanceCheck(value,constructor) true, false, or throws Validate a custom class or realm-local constructor.
symbolStringCheck(value,type) true, false, or throws Validate an intrinsic object tag.
compare(value,target,typeName) true, false, or throws Compare exact identity with Object.is.
globalInstanceCheck(value,type) true, false, or throws Guard and check a named global constructor.
nestedInstanceCheck(value,container,type) true, false, or throws Guard and check a constructor inside a namespace.
globalValueCheck(value,type) true, false, or throws Check exact identity with a named global value.
nestedValueCheck(value,container,type) true, false, or throws Check exact identity with a nested value.
union(value,types) true, false, or throws Accept one named validator from a pipe string or array.

Unions

is.union('type','string|number');
is.union(42,['string','number']);
Behavior Result
Whitespace around pipe names Trimmed
Matching validator Called once
Custom subclass validator Supported
Node adapter validator Supported through IsNode
Inherited Object method such as toString Rejected
Multi-argument helper method Rejected

Node adapter

import IsNode from 'strong-type/node';

const is=new IsNode;

is.buffer(Buffer.from('type'));
is.proxy(new Proxy({},{}));
is.nodeReadable(process.stdin);

The adapter imports Node built-ins only. It never enters the default browser-safe import graph.

Method What passes Important detail
buffer Node Buffer values A plain Uint8Array fails.
nodeStream Any classic Node Stream Web Streams use the shared validators.
nodeReadable Node Readable streams Duplex and Transform inherit Readable.
nodeWritable Node Writable streams Duplex and Transform inherit Writable.
nodeDuplex Node Duplex streams Plain readable or writable streams fail.
nodeTransform Node Transform streams PassThrough inherits Transform.
nodePassThrough Node PassThrough streams Other transforms fail.
eventEmitter Node EventEmitter instances DOM EventTarget fails.
timeout Handles returned by setTimeout Constructor is discovered lazily.
immediate Handles returned by setImmediate Constructor is discovered lazily.
keyObject Node crypto KeyObject values Web CryptoKey uses cryptoKey.
x509Certificate Node X509Certificate objects Requires a parseable certificate.
proxy Proxy values Exact util.types.isProxy check.
moduleNamespaceObject Results from import() Exact util.types check.
external Native external values Usually supplied by a native addon.
nativeError Native Error values Includes cross-realm errors.
mapIterator Native Map iterators Set iterators fail.
setIterator Native Set iterators Map iterators fail.

Direct browser use without bundling

strong-type works with bundlers and without a bundler. Bundlers resolve the bare strong-type import normally. Native browser ESM resolves that same bare import through an import map, with no build or transpilation step.

For the normal npm layout, place this complete import map before the module script:

<script type="importmap">
    {
        "imports": {
            "strong-type": "./node_modules/strong-type/index.js"
        }
    }
</script>

<script type="module">
    import Is from 'strong-type';

    const is=new Is;
    console.log(is.url(new URL('https://example.com')));
</script>

Import-map paths are relative to the HTML document. Serve the app over HTTP(S), and configure the server to expose the mapped node_modules file; file:// is not a supported module-loading path. strong-type has zero runtime dependencies, so there are no dependency entries or nested-version scopes to add.

You can also import the source directly in a native module script:

<script type="module">
    import Is from 'https://riaevangelist.github.io/strong-type/index.js';

    const is=new Is;
    console.log(is.string('native ESM'));
</script>

Use your own hosted path instead of the project Pages URL when you want to serve the file yourself. No bundle, transform, runtime shim, or host switch is involved.

Extend strong-type

import Is from 'strong-type';

class Pizza{}

class MyIs extends Is{
    pizza(value){
        return this.instanceCheck(value,Pizza);
    }
}

const is=new MyIs;

is.pizza(new Pizza);
is.union(new Pizza,'pizza|string');
Extension helper Use
this.typeCheck(value,'string') Custom typeof validator
this.instanceCheck(value,Pizza) Custom class validator
this.check(value,predicate,'description') Any custom predicate with standard strict behavior
this.throw(actual,expected) Explicit failure path

Corrected exact behavior

Version 2 removes several coercive edge cases while retaining the original method names.

Check Old behavior Current behavior
null(undefined) Passed through loose equality Fails
infinity('Infinity') Passed through loose equality Fails
finite('1') Passed through global coercive isFinite Fails
finite(null) Passed through coercion Fails
finite(1n) Could leak a native error Returns false or throws strong-type TypeError
union(value,' string | number ') Did not trim names Works
union(value,'toString') Could call an inherited method Rejected
Subclass validators in union Lost by constructing base Is Preserved

Core benchmarks

The dependency-free benchmark runner measures representative successful and rejecting core validator paths with rotating fixtures, calibrated samples, result verification, dedicated per-case loops, median timings, and median absolute deviation.

npm run benchmark
npm run benchmark:baseline
npm run benchmark:historical

The default command measures the current checkout. benchmark:baseline compares it with the pre-optimization 700059a implementation, while benchmark:historical provides a same-realm throughput reference against 1.1.0. Both comparison commands require a Git checkout containing the referenced commits. Absolute timings are harness-specific JIT throughput references, and historical results are informational because 1.1.0 did not provide the current cross-realm and spoof-resistance guarantees.

Tests and coverage

One canonical registry runs through vanilla-test 2.1.0 on Node 22.12 or newer, with every expectation assigned once to Unit, Functional, Behavioral, Integration, or Regression. CI exercises both the minimum VanillaTest runtime and Node 24. Older supported Node releases run that same registry through the small dependency-free compatibility adapter, so the development runner does not change the package's runtime support or add production dependencies.

Test suite Result on Node 24.18.0 Covers
Unit 586 passed · 13 guarded skips Atomic validator contracts across all 201 core and Node validators, including guarded capabilities
Functional 15 passed Strict and non-strict modes, unions, custom validators, and Node adapter inheritance
Behavioral 8 passed Consumer order boundaries, untrusted JSON filtering, identifier routing, domain extensions, Node uploads, and thenable safety
Integration 636 passed Reference and README completeness, browser-resolution contracts, site links, package exports, packed-consumer configuration, and CI wiring
Regression 23 passed Coercion fixes, cross-realm brands, spoof resistance, revoked proxies, and cleanup resilience
Total 1,268 passed · 0 failed · 13 skipped Five exclusive suites from one non-duplicative registry, plus the same seven shared behavioral scenarios passing in Node and Chrome

A guarded skip means the runtime does not expose that host API. It is a capability result, not an ignored failure.

Coverage uses VanillaTest's native Node V8 collector and includes only the two shipped runtime sources. Its executable-range and block-range metrics come directly from V8 and are not interchangeable with parser-derived statement or branch percentages.

Source Executable ranges Block ranges Function ranges Executable lines
index.js 90.00% · 306/340 71.05% · 81/114 99.55% · 225/226 90.87% · 926/1019
node.js 88.23% · 30/34 80.00% · 8/10 91.66% · 22/24 91.91% · 91/99
Total 89.83% · 336/374 71.77% · 89/124 98.80% · 247/250 90.96% · 1017/1118
Per-file gate Lowest current file Required
Executable ranges 88.23% 85%
Block ranges 71.05% 65%
Function ranges 91.66% 90%
Executable lines 90.87% 90%

Test and documentation files are excluded from the percentages. See the full test, coverage, and CI explanation.

Commands

Command What it does Third-party tooling
npm run benchmark Measures current core validator throughput with verified results and dispersion None
npm run benchmark:baseline Compares current core throughput with pre-optimization commit 700059a Git
npm run benchmark:historical Compares overlapping same-realm paths with 1.1.0 commit 3229b47 Git
npm test Runs Unit, Functional, Behavioral, Integration, and Regression through one registry vanilla-test 2.1.0
npm run test:unit Runs atomic core and Node validator contracts vanilla-test 2.1.0
npm run test:functional Runs public mode, union, and adapter workflows vanilla-test 2.1.0
npm run test:behavioral Runs observable consumer workflows and side-effect boundaries vanilla-test 2.1.0
npm run test:integration Runs documentation, package, site, and tooling boundaries vanilla-test 2.1.0
npm run test:regression Runs corrected edge cases and hostile-value protections vanilla-test 2.1.0
npm run test:legacy Runs the same registered cases through the compatibility adapter None
npm run test:browser Runs the shared native-browser behavioral inventory in real Chrome vanilla-test 2.1.0
npm run test:conformance Runs the same bare-import inventory in Node and real Chrome vanilla-test 2.1.0
npm run test:browser-contract Checks browser metadata, documentation, import maps, and deployment wiring None
npm run test:package Packs and installs the candidate in an isolated ESM consumer npm
npm run coverage Runs the canonical registry through VanillaTest's native Node V8 coverage collector vanilla-test 2.1.0
npm start Serves the docs and playground at http://localhost:8000/ None
npm run nodeExample Runs the Node example None

License

Migration notes · Changelog · MIT · Roshi _ _

Keywords