jestype
v1.0.0
Published
Typescript Type Tester to use with Jest
Readme
Jestype - TypeScript Type Tester for Jest
Jestype is a TypeScript utility designed to facilitate type testing within Jest, providing developers with tools to assert and validate type behaviors in TypeScript projects. At its core, expectType serves as the type-level counterpart to Jest's expect function, enabling type assertions in a manner analogous to value-based testing.
Getting Started
Install Jestype in your development environment with npm:
npm install jestype --save-devThen, import and use expectType in your Jest tests to validate types.
expectType
expectType is the primary function of Jestype and acts as the type-level equivalent of Jest's expect.
It allows type assertions for a specific type T, providing a fluent API for asserting type properties and relationships.
Usage
import { expectType } from 'jestype';
// Assert that a type is exactly another type
expectType<string>().toBe<string>();
// Assert that a type extends another type
expectType<string>().toExtend<string | number>();
// Negation example
expectType<string>().not.toBe<number>();Methods
.toBe<S>(): Asserts that the tested typeTis exactly the same as typeS..toExtend<S>(): Asserts that the tested typeTextends typeS..toBeOfUnion<S>(): Asserts that the tested typeTis part of the unionS.toHave<S>(): Asserts that the tested typeThas the same properties as typeS..toBePartOf<S>(): Asserts that the tested typeTis a subset of typeS..toHaveRequired<K extends string[]>(): Asserts that the tested typeThas all the required keys specified inK..toHaveOptional<K extends string[]>(): Asserts that the tested typeThas all the optional keys specified inK..not: Inverts the subsequent type assertion, allowing for negated checks.
Examples
.toBe<S>
Asserts that the tested type T is exactly the same as type S.
// Should pass: string is exactly a string
expectType<string>().toBe<string>();
// Should fail: string is not a number
expectType<string>().toBe<number>();
.toExtend<S>
Asserts that the tested type T extends type S.
/* Using Interfaces*/
interface Base {
baseProp: string;
}
interface Extended extends Base {
extendedProp: number;
}
// Should pass: Extended extends Base
expectType<Extended>().toExtend<Base>();
// Should fail: Base does not extend Extended
expectType<Base>().toExtend<Extended>();
/* Using Unions */
// Should pass: string is assignable to string | number
expectType<string>().toExtend<string | number>();
// Should fail: string | number is not assignable to string
expectType<string | number>().toExtend<string>();.toBeOfUnion<S>
Asserts that the tested type T is part of the union S
Exactly the same as toExtend, but lends to a more intuitive sounding type assertion for unions
// Should pass: `string` is part of union `string | number`
expectType<string>().toBeOfUnion<string | number>();
// Should fail: `string` is not in union `string | number`
expectType<string | number>().toBeOfUnion<string>();.toHave<S>
Asserts that the tested type T has the same properties as type S.
interface Person {
name: string;
age: number;
}
// Should pass: Person has name and age properties
expectType<Person>().toHave<{ name: string; age: number; }>();
// Should fail: Person does not have a salary property
expectType<Person>().toHave<{ salary: number; }>();.toBePartOf<S>
Asserts that the tested type T is a subset of type S.
interface Vehicle {
make: string;
model: string;
year: number;
}
interface Car {
make: string;
model: string;
}
// Should pass: Car is part of Vehicle
expectType<Car>().toBePartOf<Vehicle>();
// Should fail: Vehicle is not a subset of Car
expectType<Vehicle>().toBePartOf<Car>();.toHaveRequired
Asserts that the tested type T has all the required keys specified in K.
interface User {
id: number;
name: string;
email?: string;
}
// Should pass: User has required keys id and name
expectType<User>().toHaveRequired<['id', 'name']>();
// Should fail: User does not have a required key 'password'
expectType<User>().toHaveRequired<['password']>();.toHaveOptional<S>
Asserts that the tested type T has all the optional keys specified in K.
interface Product {
id: number;
name: string;
description?: string;
price?: number;
}
// Should pass: Product has optional key 'description'
expectType<Product>().toHaveOptional<['description']>();
// Should fail: Product does not have an optional key 'weight'
expectType<Product>().toHaveOptional<['weight']>();.not
Inverts the subsequent type assertion, allowing for negated checks.
// Should pass: string is not a number
expectType<string>().not.toBe<number>();
// Should fail: string is not a number
expectType<string>().<number>();Type Utilities
Jestype also includes Utility Types that expectType is built on:
Logical Types
And<T, U>: Logical AND ofTandU.Or<T, U>: Logical OR ofTandU.Not<T>: Logical NOT ofT.Nand<T, U>: Logical NAND ofTandU.Nor<T, U>: Logical NOR ofTandU.Xor<T, U>: Logical XOR ofTandU.Eq<T, U>: Checks ifTandUare equivalent.All<Items>: True if allItemsare true.Any<Items>: True if any ofItemsare true.None<Items>: True if none ofItemsare true.Switch<Condition, Inverted>: EvaluatesConditionand inverts the result ifInvertedistrue.If<Condition, Then, Else>: ReturnsThenifConditionistrue, otherwiseElse.
ExtendsTypes
Extends<T, S>: Determines if typeTextends typeS.BiExtends<T, S>: Determines if typesTandSare mutually extendable (bi-directional extends).
Key Types
RequiredKeys<T>: Extracts the required keys of typeT.OptionalKeys<T>: Extracts the optional keys of typeT.AlwaysKeys<T>: Extracts keys ofTthat are always present.
Primitive Types
IsAny<T>: Determines if typeTisany.IsNever<T>: Determines if typeTisnever.IsUnknown<T>: Determines if typeTisunknown.IsEmpty<T>: Determines if typeTis an empty object ({}).IsPrimitive<T>: Determines if typeTis a primitive type.
Branding
Brand<T>: Creates a branded representation of typeT, useful for complex type analysis.
