Smartass Assertion Functions
Smartass is an npm package that provides type-narrowing assertion functions for TypeScript projects.
Installation
Section titled “Installation”npm install -D @kensio/smartassType narrowing with assertion signatures
Section titled “Type narrowing with assertion signatures”See TypeScript assertion functions / assertion signatures
The fluent expect().toBe() interface in Jest and Vitest is readable, but is
unable to provide type information to TypeScript and IntelliSense.
This library provides assertion functions with assertion signatures so that you can benefit from the extra type information.
import { assertNonNullable } from "@kensio/smartass";
const user: { name: string } | undefined = getUser();assertNonNullable(user);// TypeScript now knows user is neither null nor undefined,// so no need for ? or ! operators.const userName = user.name;import { assertOneOf } from "@kensio/smartass";
const status = getStatus();assertOneOf(status, ["pending", "active", "completed"]);// TypeScript now knows status is of type 'pending' | 'active' | 'completed'Composable type narrowing matchers
Section titled “Composable type narrowing matchers”As well as the standalone assertion functions, you can also use type narrowing matcher functions to compose an object structure.
import { assertObjectMatches, arrayIncluding, oneOf, stringOfLength,} from "@kensio/smartass";
const user = getUser();
assertObjectMatches(user, { role: oneOf(["admin", "editor", "viewer"]), tags: arrayIncluding("beta"), id: stringOfLength(8),});
// TypeScript knows:// user.role is 'admin' | 'editor' | 'viewer'// user.tags is an array with at least one string element// user.id is a string of length 8 with safe indexingThis applies the same type narrowing effect as the assertion functions but in a composable object structure.
Assertion functions
Section titled “Assertion functions”assertArrayEqualsassertArrayIncludesAllassertArrayIncludesassertArrayLengthassertArrayMinLengthassertArrayNotEmptyassertBufferEqualassertDirectoryExistsassertFalseassertFileEqualsassertFileExistsassertFileIncludesassertFileNotIncludesassertIdenticalassertInstanceOfassertMapSizeassertNonNullableassertNumberBetweenassertNumberToNearestassertObjectEqualsassertObjectHasPropertyassertObjectMatchesassertOneOfassertPathExistsassertPathNotExistsassertSetSizeassertStringEndsWithassertStringIncludesassertStringLengthassertStringNotIncludesassertStringStartsWithassertThrowsErrorAsyncassertThrowsErrorLikeassertThrowsErrorassertTrueassertTypeBigIntassertTypeBooleanassertTypeFunctionassertTypeNumberassertTypeNumericassertTypeObjectassertTypeStringassertTypeSymbolassertTypeTypedArrayassertUndefinedassertUuidV4
Matcher functions
Section titled “Matcher functions”arrayIncludingAllarrayIncludingarrayOfLengtharrayOfMinLengthnonEmptyArraybufferEqualToinstanceOfmapOfSizenonNullablenumberBetweennumberToNearestobjectWithPropertyoneOfsetOfSizestringEndingWithstringIncludingstringOfLengthstringNotIncludingstringStartingWithtypeBigInttypeBooleantypeFunctiontypeNumbertypeNumerictypeObjecttypeStringtypeSymboltypeTypedArrayuuidV4
Optional ESLint config
Section titled “Optional ESLint config”The @kensio/smartass package also exports an optional ESLint flat config that discourages less
specific assertion usage. For example:
assertIdentical(foo.length, 2);// suggested improvement:assertArrayLength(foo, 2);You can use this in your ESLint config like this:
import { defineConfig } from "eslint/config";import tseslint from "typescript-eslint";
import { smartassPreferSpecificAssertions } from "@kensio/smartass/eslint";
export default defineConfig( ...tseslint.configs.recommended, ...smartassPreferSpecificAssertions,);