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 🙏

© 2024 – Pkg Stats / Ryan Hefner

ts-expect

v1.3.0

Published

Checks TypeScript types match expected values

Downloads

529,166

Readme

TS Expect

NPM version NPM downloads Build status Test coverage

Checks values in TypeScript match expectations.

Installation

npm install ts-expect --save

Usage

TS Expect exports a function, named expectType, that does nothing at all. Instead, it depends on the TypeScript compiler and a generic to test the type of a "value" passed to expectType is assignable to its generic in the type system.

import { expectType } from "ts-expect";

expectType<string>("test");
expectType<number>(123);
expectType<number>("test"); // Compiler error!

How does this work?

TypeScript generics allow you to pass any value that implements the generic type. In this case, we're defining the generic explicitly as we pass the value so any value that isn't implementing our type is rejected by the TypeScript compiler. It's really that simple! The technical implementation is just <T>(value: T) => void.

TypeScript has a "top type" named unknown and a "bottom type" named never. Using the top type to check assignability would mean every value is accepted, and the bottom type would mean nothing is accepted (except never itself). As a result, you probably wouldn't want to use unknown because everything would pass that check.

A quick note on any: it's an "off switch" for TypeScript. It acts as a magical every type, both a top and a bottom type. This means it's assignable to everything and passing an any value to expectType will always pass the check.

Testing definitions

Use with built-in or custom TypeScript utility types to implement a simple testing framework for your type definitions. If it compiles, it's valid!

import { expectType, TypeEqual } from "ts-expect";
import { add } from "./adder";

expectType<number>(add(1, 2));
expectType<TypeEqual<boolean, ReturnType<typeof add>>>(true);
expectType<TypeEqual<[number, number], Parameters<typeof add>>>(true);

Exhaustive checks

Use with TypeScript's type narrowing to test that value is what you expect. If you expand SupportedValue with other values in the future, it'll fail an expectType<never> or expectNever check because you haven't used all the possible values.

import { expectNever } from "ts-expect";

type SupportedValue = "a" | "b";

function doSomething(value: SupportedValue) {
  switch (value) {
    case "a":
      return true;
    case "b":
      return true;
    default:
      return expectNever(value);
  }
}

Tip: Use expectNever(value) when you need to return never (i.e. throw an error if the code runs), use expectType<never>(value) when you want to do tests in your code and expect the actual expression to be executed (i.e. do type checks but ignore the runtime).

Exported Types

TS Expect comes with some utility types built-in to make testing easier. File an issue if you think something is missing!

TypeEqual<Target, Value>

Checks that Value is equal to the same type as Target. This is a stricter check that avoids issues with testing sub-types. If you want to verify that an object is identical shape, not just "implements" Target, this is the type you need.

TypeOf<Target, Value>

Checks that Value is assignable to Target. This is effectively the same as expectType<Type>(value), except it's implemented in the type system directly so you can use it to test types instead of values by checking the result is true or false.

Prior Works

Some great prior works have been mentioned after publishing this package:

  • dtslint does type checks via comment directives and inspired this approach of using the compiler
  • tsd-check is a CLI that runs the TypeScript type checker over assertions
  • type-plus comes with various type and runtime TypeScript assertions
  • static-type-assert exposes a similar API surface with some type assertion functions

License

MIT