Compile-time tests for types to make sure types don't regress into being overly permissive as changes go in over time.
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Comprehensive function type checking including parameters, return types, overloads, callability, and constructor analysis.
Extract and validate individual function parameters and parameter tuples.
/**
* Extract a specific function parameter by index
* @param index - Zero-based parameter index
* @returns ExpectTypeOf for the parameter type at the given index
*/
parameter<Index extends number>(index: Index): ExpectTypeOf<OverloadParameters<Actual>[Index], Options>;
/**
* Extract all function parameters as a tuple
* For overloaded functions, returns union of all parameter tuples
*/
parameters: ExpectTypeOf<OverloadParameters<Actual>, Options>;Usage Examples:
import { expectTypeOf } from "expect-type";
// Single parameter function
const add = (a: number, b: number) => a + b;
expectTypeOf(add).parameter(0).toBeNumber();
expectTypeOf(add).parameter(1).toBeNumber();
expectTypeOf(add).parameters.toEqualTypeOf<[number, number]>();
// No parameter function
const noArgs = () => "hello";
expectTypeOf(noArgs).parameters.toEqualTypeOf<[]>();
// Optional parameters
const withOptional = (required: string, optional?: number) => ({ required, optional });
expectTypeOf(withOptional).parameters.toEqualTypeOf<[string, number?]>();
// Rest parameters
const withRest = (first: string, ...rest: number[]) => ({ first, rest });
expectTypeOf(withRest).parameters.toEqualTypeOf<[string, ...number[]]>();Analyze function return types with support for overloaded functions.
/**
* Extract function return type
* For overloaded functions, returns union of all return types
*/
returns: ExpectTypeOf<OverloadReturnTypes<Actual>, Options>;Usage Examples:
import { expectTypeOf } from "expect-type";
// Basic return type
const getString = () => "hello";
expectTypeOf(getString).returns.toBeString();
// Function returning computed type
const getArray = (x: number) => [x, x];
expectTypeOf(getArray).returns.toEqualTypeOf<[number, number]>();
// Void return
const logMessage = (msg: string) => console.log(msg);
expectTypeOf(logMessage).returns.toBeVoid();
// Never return (functions that throw)
const throwError = (): never => { throw new Error("fail"); };
expectTypeOf(throwError).returns.toBeNever();
// Async function returns
const asyncFn = async () => 42;
expectTypeOf(asyncFn).returns.resolves.toBeNumber();Test whether functions can be called with specific argument types.
/**
* Check if function is callable with given parameters
* Returns narrowed type for overloaded functions
* Note: Cannot be negated with .not - use @ts-expect-error instead
* @param args - Arguments to test callability with
* @returns ExpectTypeOf for the narrowed function type
*/
toBeCallableWith<Args extends OverloadParameters<Actual>>(
...args: Args
): ExpectTypeOf<OverloadsNarrowedByParameters<Actual, Args>, Options>;Usage Examples:
import { expectTypeOf } from "expect-type";
// Basic callability
const multiply = (a: number, b: number) => a * b;
expectTypeOf(multiply).toBeCallableWith(5, 10);
// Overloaded function callability
type Factorize = {
(input: number): number[];
(input: bigint): bigint[];
};
declare const factorize: Factorize;
expectTypeOf(factorize).toBeCallableWith(6);
expectTypeOf(factorize).toBeCallableWith(6n);
// Narrow return type based on parameters
expectTypeOf(factorize)
.toBeCallableWith(6)
.returns.toEqualTypeOf<number[]>();
expectTypeOf(factorize)
.toBeCallableWith(6n)
.returns.toEqualTypeOf<bigint[]>();
// Complex overload narrowing
type Delete = {
(path: string): void;
(paths: string[], options?: { force: boolean }): void;
};
declare const deleteFiles: Delete;
expectTypeOf(deleteFiles)
.toBeCallableWith("file.txt")
.parameters.toEqualTypeOf<[string]>();
expectTypeOf(deleteFiles)
.toBeCallableWith(["file1.txt", "file2.txt"], { force: true })
.parameters.toEqualTypeOf<[string[], { force: boolean }?]>();
// Invalid calls (use @ts-expect-error)
// @ts-expect-error
expectTypeOf(multiply).toBeCallableWith("invalid");Analyze class constructors and their parameters.
/**
* Check if constructor is callable with given parameters
* @param args - Constructor arguments to test
* @returns true if constructor is callable with given arguments
*/
toBeConstructibleWith<Args extends ConstructorOverloadParameters<Actual>>(
...args: Args
): boolean;
/**
* Extract constructor parameter types
* For overloaded constructors, returns union of all parameter tuples
*/
constructorParameters: ExpectTypeOf<ConstructorOverloadParameters<Actual>, Options>;
/**
* Extract instance type of a constructor
*/
instance: ExpectTypeOf<InstanceType<Actual>, Options>;Usage Examples:
import { expectTypeOf } from "expect-type";
// Built-in constructor
expectTypeOf(Date).toBeConstructibleWith();
expectTypeOf(Date).toBeConstructibleWith("2023-01-01");
expectTypeOf(Date).toBeConstructibleWith(0);
expectTypeOf(Date).toBeConstructibleWith(new Date());
expectTypeOf(Date).constructorParameters.toEqualTypeOf<
| []
| [value: string | number | Date]
| [year: number, monthIndex: number, date?: number, hours?: number, minutes?: number, seconds?: number, ms?: number]
>();
// Custom class with overloaded constructor
class DatabaseConnection {
constructor();
constructor(connectionString: string);
constructor(options: { host: string; port: number });
constructor(..._: unknown[]) {}
}
expectTypeOf(DatabaseConnection).toBeConstructibleWith();
expectTypeOf(DatabaseConnection).toBeConstructibleWith("localhost:5432");
expectTypeOf(DatabaseConnection).toBeConstructibleWith({
host: "localhost",
port: 5432
});
// Instance type checking
expectTypeOf(Date).instance.toHaveProperty("toISOString");
expectTypeOf(Array).instance.toHaveProperty("push");
expectTypeOf(Array).instance.toHaveProperty("length");Analyze the this parameter type of functions.
/**
* Extract the this parameter type of a function
* Equivalent to TypeScript's ThisParameterType utility type
*/
thisParameter: ExpectTypeOf<ThisParameterType<Actual>, Options>;Usage Examples:
import { expectTypeOf } from "expect-type";
// Function with explicit this parameter
function greet(this: { name: string }, message: string) {
return `Hello ${this.name}, ${message}`;
}
expectTypeOf(greet).thisParameter.toEqualTypeOf<{ name: string }>();
// Distinguish functions with different this parameters
function greetFormal(
this: { title: string; name: string },
message: string
) {
return `Dear ${this.title} ${this.name}, ${message}`;
}
function greetCasual(this: { name: string }, message: string) {
return `Hi ${this.name}, ${message}`;
}
expectTypeOf(greetFormal).not.toEqualTypeOf(greetCasual);
expectTypeOf(greetFormal).thisParameter.toEqualTypeOf<{
title: string;
name: string;
}>();
expectTypeOf(greetCasual).thisParameter.toEqualTypeOf<{ name: string }>();
// Regular functions without explicit this
const regularFunction = (x: number) => x * 2;
expectTypeOf(regularFunction).thisParameter.toBeUnknown();Handle function overloads properly, unlike TypeScript's built-in Parameters and ReturnType utilities.
import { expectTypeOf } from "expect-type";
// Overloaded function
type StringOrNumberProcessor = {
(input: string): string[];
(input: number): number[];
};
declare const processor: StringOrNumberProcessor;
// expect-type handles all overloads
expectTypeOf(processor).parameters.toEqualTypeOf<[string] | [number]>();
expectTypeOf(processor).returns.toEqualTypeOf<string[] | number[]>();
// TypeScript built-ins only handle last overload
expectTypeOf<Parameters<StringOrNumberProcessor>>().toEqualTypeOf<[number]>();
expectTypeOf<ReturnType<StringOrNumberProcessor>>().toEqualTypeOf<number[]>();
// Access specific overload via parameter narrowing
expectTypeOf(processor).parameter(0).toEqualTypeOf<string | number>();Analyze type guard and assertion functions.
/**
* Extract the type guarded by a type guard function
* Works with functions that return `v is T`
*/
guards: ExpectTypeOf<GuardedType, Options>;
/**
* Extract the type asserted by an assertion function
* Works with functions that use `asserts v is T`
*/
asserts: ExpectTypeOf<AssertedType, Options>;Usage Examples:
import { expectTypeOf } from "expect-type";
// Type guard function
function isString(value: unknown): value is string {
return typeof value === "string";
}
expectTypeOf(isString).guards.toBeString();
function isBigInt(value: unknown): value is bigint {
return typeof value === "bigint";
}
expectTypeOf(isBigInt).guards.toBeBigInt();
// Assertion function
function assertIsNumber(value: unknown): asserts value is number {
if (typeof value !== "number") {
throw new TypeError("Expected number");
}
}
expectTypeOf(assertIsNumber).asserts.toBeNumber();
// Complex type guards
function isUser(value: unknown): value is { name: string; age: number } {
return typeof value === "object" &&
value !== null &&
"name" in value &&
"age" in value;
}
expectTypeOf(isUser).guards.toEqualTypeOf<{ name: string; age: number }>();Generic Functions: toBeCallableWith may fail with generic functions. Use type assertions or specific instantiations.
Complex Overloads: Functions with more than 10 overloads may not be fully analyzed.
This References: Cannot pass this directly to expectTypeOf within class methods. Use .instance instead.