Check TypeScript type definitions with static analysis and comprehensive assertion functions
—
Main testing function and diagnostic formatter for integration with testing frameworks and custom workflows. Provides programmatic access to TSD's type checking capabilities.
The primary function for programmatically running type definition tests.
/**
* Type check the type definition of the project
* @param options - Configuration options for type checking (defaults to {cwd: process.cwd()})
* @returns Promise resolving to array of diagnostics
*/
function tsd(options?: Options): Promise<Diagnostic[]>;
interface Options {
/** Current working directory of the project to retrieve diagnostics for */
cwd: string;
/** Path to the type definition file you want to test */
typingsFile?: string;
/** Array of test files with their path */
testFiles?: readonly string[];
}Usage Examples:
import tsd from "tsd";
// Basic usage - test current directory
const diagnostics = await tsd();
console.log(`Found ${diagnostics.length} issues`);
// Custom working directory
const diagnostics = await tsd({
cwd: "/path/to/my-project"
});
// Specific typings file
const diagnostics = await tsd({
cwd: "/path/to/project",
typingsFile: "dist/custom.d.ts"
});
// Custom test files
const diagnostics = await tsd({
cwd: "/path/to/project",
testFiles: ["tests/types/*.test-d.ts", "src/**/*.test-d.ts"]
});
// Check for errors
const hasErrors = diagnostics.some(d => d.severity === "error");
if (hasErrors) {
process.exit(1);
}Format diagnostics for human-readable output, matching the CLI formatter.
/**
* Format the TypeScript diagnostics to human readable output
* @param diagnostics - List of TypeScript diagnostics
* @param showDiff - Display difference between expected and received types
* @returns Formatted diagnostics output
*/
function formatter(diagnostics: Diagnostic[], showDiff?: boolean): string;Usage Examples:
import tsd, { formatter } from "tsd";
const diagnostics = await tsd();
// Basic formatting
if (diagnostics.length > 0) {
console.log(formatter(diagnostics));
}
// With type difference display
const formattedWithDiff = formatter(diagnostics, true);
console.log(formattedWithDiff);
// Custom error handling
if (diagnostics.length > 0) {
const hasErrors = diagnostics.some(d => d.severity === "error");
const hasWarnings = diagnostics.some(d => d.severity === "warning");
console.log(`Found ${diagnostics.length} issues:`);
console.log(`- Errors: ${diagnostics.filter(d => d.severity === "error").length}`);
console.log(`- Warnings: ${diagnostics.filter(d => d.severity === "warning").length}`);
console.log("\nDetails:");
console.log(formatter(diagnostics, true));
if (hasErrors) {
process.exit(1);
}
}import test from "ava";
import tsd from "tsd";
test("type definitions", async (t) => {
const diagnostics = await tsd();
t.is(diagnostics.length, 0, "No type errors expected");
// Or check specific diagnostics
const errors = diagnostics.filter(d => d.severity === "error");
t.is(errors.length, 0, `Found ${errors.length} type errors`);
});import tsd from "tsd";
describe("Type Definitions", () => {
it("should have no type errors", async () => {
const diagnostics = await tsd();
const errors = diagnostics.filter(d => d.severity === "error");
expect(errors).toHaveLength(0);
});
it("should validate specific type file", async () => {
const diagnostics = await tsd({
typingsFile: "dist/api.d.ts",
testFiles: ["tests/api.test-d.ts"]
});
expect(diagnostics.filter(d => d.severity === "error")).toHaveLength(0);
});
});import { expect } from "chai";
import tsd from "tsd";
describe("Type Definitions", () => {
it("should pass all type tests", async () => {
const diagnostics = await tsd();
const errors = diagnostics.filter(d => d.severity === "error");
expect(errors).to.have.lengthOf(0);
});
});import tsd, { formatter } from "tsd";
import fs from "fs/promises";
async function validateTypes(projectPath: string): Promise<boolean> {
try {
const diagnostics = await tsd({
cwd: projectPath
});
if (diagnostics.length === 0) {
console.log("✅ All type tests passed");
return true;
}
const errors = diagnostics.filter(d => d.severity === "error");
const warnings = diagnostics.filter(d => d.severity === "warning");
console.log(`Found ${diagnostics.length} issues:`);
console.log(`- ${errors.length} errors`);
console.log(`- ${warnings.length} warnings`);
// Write detailed report to file
const report = formatter(diagnostics, true);
await fs.writeFile("type-check-report.txt", report);
// Print summary to console
console.log(formatter(diagnostics));
return errors.length === 0;
} catch (error) {
console.error("Type checking failed:", error.message);
return false;
}
}
// Usage
const success = await validateTypes("/path/to/project");
process.exit(success ? 0 : 1);Common Error Scenarios:
TSD uses a custom error class internally but does not export it directly. Errors can be identified by checking the constructor name.
import tsd from "tsd";
try {
const diagnostics = await tsd({
cwd: "/invalid/path"
});
} catch (error) {
// TsdError is not directly exported but is thrown by the main function
if (error && typeof error === 'object' && error.constructor.name === 'TsdError') {
// Handle TSD-specific errors
console.error("TSD Error:", error.message);
// Common error messages:
// - "No `package.json` file found in `<path>`"
// - "The type definition `<file>` does not exist at `<path>`"
// - "Could not find any test files with the given pattern(s)"
// - "The test file `<file>` does not exist in `<path>`"
} else {
// Handle other errors
console.error("Unexpected error:", error);
}
}The programmatic API respects package.json configuration:
{
"name": "my-package",
"tsd": {
"directory": "type-tests",
"compilerOptions": {
"strict": false,
"target": "es2020"
}
}
}TSD automatically loads TypeScript configuration from tsconfig.json:
import tsd from "tsd";
// This will use project's tsconfig.json automatically
const diagnostics = await tsd({
cwd: "/path/to/project-with-tsconfig"
});import tsd from "tsd";
// For large projects, consider limiting test files
const diagnostics = await tsd({
testFiles: ["src/**/*.test-d.ts"], // Only test src directory
});
// Or test specific areas incrementally
const apiDiagnostics = await tsd({
typingsFile: "dist/api.d.ts",
testFiles: ["tests/api.test-d.ts"]
});
const utilsDiagnostics = await tsd({
typingsFile: "dist/utils.d.ts",
testFiles: ["tests/utils.test-d.ts"]
});Install with Tessl CLI
npx tessl i tessl/npm-tsd