https://github.com/nyaomaru/is-kit
Lightweight, zero-dependency toolkit for building `isFoo` style type guards in TypeScript. Runtime-safe 🛡️, composable 🧩, and ergonomic ✨. npm -> https://www.npmjs.com/package/is-kit
https://github.com/nyaomaru/is-kit
is is-kit open-source runtime-type-checking type-guard type-guards type-safe typescript utility validation
Last synced: 16 days ago
JSON representation
Lightweight, zero-dependency toolkit for building `isFoo` style type guards in TypeScript. Runtime-safe 🛡️, composable 🧩, and ergonomic ✨. npm -> https://www.npmjs.com/package/is-kit
- Host: GitHub
- URL: https://github.com/nyaomaru/is-kit
- Owner: nyaomaru
- License: mit
- Created: 2025-10-01T10:54:11.000Z (5 months ago)
- Default Branch: main
- Last Pushed: 2026-02-14T12:06:44.000Z (23 days ago)
- Last Synced: 2026-02-14T20:19:46.337Z (23 days ago)
- Topics: is, is-kit, open-source, runtime-type-checking, type-guard, type-guards, type-safe, typescript, utility, validation
- Language: TypeScript
- Homepage: https://is-kit-docs.vercel.app
- Size: 595 KB
- Stars: 28
- Watchers: 1
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
- Code of conduct: CODE_OF_CONDUCT.md
- Agents: AGENTS.md
Awesome Lists containing this project
README
# is-kit
Lightweight, zero-dependency toolkit for building `isFoo` style type guards in TypeScript.
Runtime-safe 🛡️, composable 🧩, and ergonomic ✨.
[📚 full documentation](https://is-kit-docs.vercel.app/)
## Why?
Tired of writing the same `isFoo` again and again?
Let `is-kit` do it for you:
- Less boilerplate
- Type-safe
- Composable
- Zero-dependency
> ☕ Grab a coffee, let `is-kit` do the boring work.
## Install
Node via npm
```bash
pnpm add is-kit
# or
bun add is-kit
# or
npm i is-kit
# or
yarn add is-kit
```
ESM and CJS builds are provided for npm consumers. Types are bundled.
### JSR (TypeScript source)
```ts
// Deno/Bun/JSR-aware tooling
import { define, and, or } from 'jsr:@nyaomaru/is-kit';
```
## Quick start
Build `is` functions from tiny, composable pieces:
```ts
import {
define,
and,
or,
not,
struct,
oneOfValues,
optional,
isNumber,
isString,
predicateToRefine
} from 'is-kit';
// Define small guards
const isShortString = define((v) => isString(v) && v.length <= 3);
const isPositive = and(
isNumber,
predicateToRefine((v) => v > 0)
);
// Combine them (or / not)
const isShortOrPositive = or(isShortString, isPositive);
const isOther = not(isShortOrPositive);
// Define object shapes
const isRole = oneOfValues(['admin', 'member'] as const);
const isUser = struct({
id: isPositive, // number > 0
name: isString, // string
role: isRole, // 'admin' | 'member'
nickname: optional(isShortString) // string <= 3 | undefined
});
// Use them
isPositive(3); // true
isShortOrPositive('foo'); // true
isShortOrPositive(false); // false
isOther('x'); // true
const maybeUser: unknown = { id: 7, name: 'Rin', role: 'admin' };
if (isUser(maybeUser)) {
// The type is narrowed inside this block
maybeUser.role; // 'admin' | 'member'
maybeUser.nickname?.toUpperCase();
}
```
Composed guards stay reusable:
`isPositive` can be used standalone or as part of a `struct` definition.
When validating complex shapes, reach for `struct` — and friends like `arrayOf`, `recordOf`, or `oneOf`.
### Primitive guards
Built-in primitives: `isString`, `isNumber` (finite), `isBoolean`, `isBigInt`, `isSymbol`, `isUndefined`, `isNull` — and a preset `isPrimitive` for any primitive.
Numeric helpers are included for common cases: `isInteger`, `isSafeInteger`, `isPositive`, `isNegative`, `isZero`, `isNaN`, `isInfiniteNumber`.
```ts
import {
isPrimitive,
isNumber,
isInteger,
isSafeInteger,
isPositive,
isNegative,
isZero,
isNaN,
isInfiniteNumber
} from 'is-kit';
// Any primitive
isPrimitive('x'); // true
isPrimitive(123); // true
isPrimitive(NaN); // true (use isNumber for finite only)
isPrimitive({}); // false
// Numeric helpers
isNumber(10); // true
isInteger(42); // true
isSafeInteger(2 ** 53); // false
isPositive(3); // true
isPositive(0); // false
isNegative(-3); // true
isNegative(-0); // false
isZero(0); // true
isZero(1); // false
isNaN(NaN); // true
isNaN(0); // false
isInfiniteNumber(Infinity); // true
isInfiniteNumber(1); // false
```
### Object guards
Object/built-in guards cover arrays, dates, maps/sets, and more. Use
`isInstanceOf` when you want a reusable guard from a class constructor.
```ts
import { isArray, isDate, isInstanceOf } from 'is-kit';
class Animal {}
class Dog extends Animal {}
const isAnimal = isInstanceOf(Animal);
isArray([]); // true
isDate(new Date()); // true
isAnimal(new Dog()); // true
isAnimal({}); // false
```
## Core Ideas
- **Define once**: `define(fn)` turns a plain function into a type guard.
- **Upgrade predicates**: `predicateToRefine(fn)` adds narrowing.
- **Compose freely**: `and`, `or`, `not`, `oneOf`, `arrayOf`, `struct` …
- **Stay ergonomic**: helpers like `nullable`, `optional`, `equals`, `safeParse`, `assert`, `hasKey`, `narrowKeyTo`.
### Key Helpers
Use `hasKey` to check for a required own property before refining, and
`narrowKeyTo` when you need to narrow a property to a specific literal value.
```ts
import { hasKey, isString, isNumber, narrowKeyTo, or, struct } from 'is-kit';
// Base guard (e.g., via struct)
type User = { id: string; age: number; role: 'admin' | 'guest' | 'trial' };
const isUser = struct({
id: isString,
age: isNumber,
role: oneOfValues('admin', 'guest', 'trial')
});
const hasRole = hasKey('role');
const byRole = narrowKeyTo(isUser, 'role');
const isGuest = byRole('guest'); // Readonly & { role: 'guest' }
const isTrial = byRole('trial'); // Readonly & { role: 'trial' }
const isGuestOrTrial = or(isGuest, isTrial);
declare const value: unknown;
if (hasRole(value)) {
value.role;
}
if (isGuestOrTrial(value)) {
// value.role is 'guest' | 'trial'
}
```
## API Reference
For full API details and runnable examples, visit
[📚 See full document](https://is-kit-docs.vercel.app/)
## Development
Requires Node 22 and pnpm 10.12.4 (via Corepack or mise).
Want to hack on `is-kit`?
See `DEVELOPER.md` for setup, scripts, and contribution workflow.
## Contributing
See `CONTRIBUTE.md` for workflow, commit style, and tool setup. 🚀