CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-tsd

Check TypeScript type definitions with static analysis and comprehensive assertion functions

Pending
Overview
Eval results
Files

programmatic-api.mddocs/

Programmatic API

Main testing function and diagnostic formatter for integration with testing frameworks and custom workflows. Provides programmatic access to TSD's type checking capabilities.

Capabilities

Main TSD Function

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);
}

Diagnostic Formatter

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);
  }
}

Integration with Testing Frameworks

AVA Integration

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`);
});

Jest Integration

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);
  });
});

Mocha Integration

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);
  });
});

Custom Validation Workflows

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);

Error Handling

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);
  }
}

Configuration Integration

Package.json Configuration

The programmatic API respects package.json configuration:

{
  "name": "my-package",
  "tsd": {
    "directory": "type-tests",
    "compilerOptions": {
      "strict": false,
      "target": "es2020"
    }
  }
}

TypeScript Configuration

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"
});

Performance Considerations

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

docs

assertions.md

cli.md

index.md

programmatic-api.md

tile.json