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 🙏

© 2026 – Pkg Stats / Ryan Hefner

ts-semver-detector

v0.3.1

Published

A CLI tool to analyze changes between TypeScript definition files and determine semantic version increments

Readme

TypeScript Definition Change Analyzer

A command-line tool that analyzes changes between TypeScript definition files (.d.ts) to automatically determine the appropriate semantic version increment based on the nature of the changes.

Features

  • Analyzes changes between two TypeScript definition files
  • Determines appropriate semantic version bump (MAJOR, MINOR, PATCH)
  • Detects various types of changes:
    • Interface modifications
    • Type changes (including union types and conditional types)
    • Function signature changes
    • Export additions/removals
    • Conditional type analysis (new in v0.3.0)
    • Mapped type changes
  • Provides detailed change reports in JSON format
  • Includes location information for each change
  • Supports CI/CD integration
  • Configurable rules and behavior
  • Plugin system for custom rules

Installation

npm install -g ts-semver-detector

Usage

Basic usage:

ts-semver-detector --old oldFile.d.ts --new newFile.d.ts

With options:

ts-semver-detector --old oldFile.d.ts --new newFile.d.ts --output report.json --config ./config.js

Options

  • --old <file>: Path to the old .d.ts file (required)
  • --new <file>: Path to the new .d.ts file (required)
  • --format <type>: Output format (json) (default: "json")
  • --output <file>: Output file path
  • --verbose: Show detailed information about changes
  • --config <file>: Path to config file
  • --ignore-private: Ignore private members (default: true)
  • --ignore-internal: Ignore internal members (default: false)
  • --treat-missing-as-undefined: Treat missing types as undefined (default: false)
  • --treat-undefined-as-any: Treat undefined as any (default: false)

Configuration

The tool can be configured using a configuration file. It supports the following formats:

  • JavaScript file (ts-semver-detector.config.js)
  • JSON file (ts-semver-detector.config.json)
  • RC file (.ts-semver-detectorrc, .ts-semver-detectorrc.json, .ts-semver-detectorrc.js)

Example configuration file:

module.exports = {
  // Patterns to ignore when analyzing files
  ignorePatterns: [
    "**/node_modules/**",
    "**/dist/**",
    "**/build/**",
    "**/*.test.d.ts",
  ],

  // Override rule severities
  ruleOverrides: [
    {
      id: "interface-change",
      severity: "major", // Always treat interface changes as major
    },
    {
      id: "type-change",
      enabled: false, // Disable type change detection
    },
  ],

  // General options
  ignorePrivateMembers: true,
  ignoreInternalMembers: true,
  treatMissingAsUndefined: false,
  treatUndefinedAsAny: false,

  // Custom rules can be added here
  customRules: [],
};

Configuration Options

General Options

  • ignorePatterns: Array of glob patterns to ignore when analyzing files
  • ignorePrivateMembers: Whether to ignore private class members (default: true)
  • ignoreInternalMembers: Whether to ignore internal declarations (default: false)
  • treatMissingAsUndefined: Whether to treat missing types as undefined (default: false)
  • treatUndefinedAsAny: Whether to treat undefined as any (default: false)

Rule Overrides

Rule overrides allow you to customize the behavior of built-in rules:

ruleOverrides: [
  {
    id: "rule-id", // Rule identifier
    severity: "major", // Override severity (major, minor, patch)
    enabled: true, // Enable/disable the rule
  },
];

Available rules:

  • interface-change: Detects changes in interface declarations
  • type-change: Detects changes in type aliases
  • function-change: Detects changes in function signatures
  • class-change: Detects changes in class declarations
  • conditional-type-change: Detects changes in conditional types (v0.3.0+)
  • mapped-type-change: Detects changes in mapped types

Custom Rules

You can add custom rules by implementing the Rule interface:

interface Rule {
  id: string;
  description: string;
  analyze(oldNode: ts.Node, newNode: ts.Node): Change | null;
}

Example custom rule:

class CustomRule implements Rule {
  id = "custom-rule";
  description = "Custom rule description";

  analyze(oldNode: ts.Node, newNode: ts.Node): Change | null {
    // Implement your rule logic here
    return {
      type: "other",
      name: "custom",
      change: this.id,
      severity: "major",
      description: "Custom change detected",
    };
  }
}

// Add to configuration
module.exports = {
  customRules: [new CustomRule()],
};

Change Classification

The tool classifies changes according to semantic versioning principles:

MAJOR Version Bump (Breaking Changes)

  • Removing exported declarations
  • Narrowing type definitions
  • Adding required properties to interfaces
  • Incompatible function signature changes
  • Removing implemented interfaces
  • Changing public members to private/protected

MINOR Version Bump (Backwards-Compatible Additions)

  • Adding new exports
  • Adding optional properties
  • Broadening type definitions
  • Adding optional parameters
  • Adding new public members
  • Adding implemented interfaces

PATCH Version Bump

  • Documentation changes
  • Formatting changes
  • No functional changes
  • Equivalent type reformatting

Conditional Type Analysis (New in v0.3.0)

The tool now provides comprehensive analysis of conditional type changes, which are critical for maintaining type safety in complex TypeScript libraries.

Conditional Type Changes

Conditional types follow the pattern T extends U ? X : Y and changes to them are classified as follows:

MAJOR Changes (Breaking)

  • Narrowed conditions: Making the condition more restrictive

    // Old: More permissive condition
    type IsString<T> = T extends string | number ? true : false;
    
    // New: More restrictive condition (MAJOR)
    type IsString<T> = T extends string ? true : false;
  • Changed default branch to never: Making the fallback case more restrictive

    // Old: Fallback returns the original type
    type UnwrapPromise<T> = T extends Promise<infer U> ? U : T;
    
    // New: Fallback returns never (MAJOR)
    type UnwrapPromise<T> = T extends Promise<infer U> ? U : never;

MINOR Changes (Backwards-Compatible)

  • Broadened conditions: Making the condition more permissive

    // Old: More restrictive condition
    type IsString<T> = T extends string ? true : false;
    
    // New: More permissive condition (MINOR)
    type IsString<T> = T extends string | number ? true : false;
  • Enhanced true/false branches: Adding more specific return types

    // Old: Simple boolean return
    type IsString<T> = T extends string ? true : false;
    
    // New: More specific return types (MINOR)
    type IsString<T> = T extends string ? "string" : "not-string";

The analyzer automatically detects these patterns and classifies them appropriately, helping you maintain semantic versioning compliance when working with complex conditional types.

Output Formats

Text Output

TypeScript Definition Changes Analysis

Recommended Version Bump:
MAJOR

Changes:
MAJOR interface: Added required property 'language' to interface 'UserSettings'
MINOR interface: Added optional property 'age' to interface 'User'
...

Summary:
Major Changes: 1
Minor Changes: 1
Patch Changes: 0

JSON Output

{
  "recommendedVersionBump": "major",
  "changes": [
    {
      "type": "interface",
      "name": "UserSettings",
      "change": "added-required-property",
      "severity": "major",
      "description": "Added required property 'language'",
      "location": {
        "newFile": { "line": 5, "column": 3 }
      }
    }
  ],
  "summary": {
    "majorChanges": 1,
    "minorChanges": 1,
    "patchChanges": 0
  }
}

CI Integration

GitHub Actions Example

name: API Version Check

on:
  pull_request:
    paths:
      - "**/*.d.ts"

jobs:
  check-version:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Setup Node.js
        uses: actions/setup-node@v2
        with:
          node-version: "16"
      - name: Install ts-semver-detector
        run: npm install -g ts-semver-detector
      - name: Check TypeScript API changes
        run: |
          ts-semver-detector \
            --old ${{ github.event.pull_request.base.sha }}:types/index.d.ts \
            --new ${{ github.event.pull_request.head.sha }}:types/index.d.ts \
            --format json \
            --output report.json

GitLab CI Example

api-version-check:
  script:
    - npm install -g ts-semver-detector
    - ts-semver-detector \
      --old ${CI_MERGE_REQUEST_DIFF_BASE_SHA}:types/index.d.ts \
      --new ${CI_MERGE_REQUEST_TARGET_BRANCH_SHA}:types/index.d.ts \
      --format json \
      --output changes.json
  only:
    - merge_requests
  changes:
    - "**/*.d.ts"

Development

Setup

git clone https://github.com/yourusername/ts-semver-detector.git
cd ts-semver-detector
npm install

Running Tests

npm test

Building

npm run build

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

MIT