TypeScript Type Immutability Checker

5.0.1 · active · verified Sun Apr 19

is-immutable-type is a TypeScript utility library designed to statically analyze the immutability of TypeScript types within a given program context. It provides detailed classifications for types, distinguishing between `Immutable` (deeply read-only, no modifications possible), `ReadonlyDeep` (deeply immutable data, but methods are not), `ReadonlyShallow` (shallowly immutable, but deep values are not), `Mutable` (shallowly mutable), and `Unknown` (immutability could not be determined). The library is currently on version 5.0.1 and maintains an active release cadence, with several major and minor versions released recently, indicating continuous development. Its key differentiators include precise immutability definitions and a robust override mechanism, allowing developers to specify immutability for types where static analysis alone might be insufficient. It is typically integrated into TypeScript tooling like ESLint plugins for advanced type-aware linting.

Common errors

Warnings

Install

Imports

Quickstart

This example demonstrates how to use `getTypeImmutability` with a TypeScript program and AST node, showing how to interpret the returned `Immutability` enum value using helper functions.

import { Immutability, getTypeImmutability, isReadonlyDeep, isUnknown } from 'is-immutable-type';
import { hasType } from 'ts-api-utils';
import type ts from 'typescript';

/**
 * Demonstrates how to get and interpret the immutability of a TypeScript type.
 * This example requires a TypeScript Program instance and a Node from its AST.
 * @param program The TypeScript program instance.
 * @param node The AST node whose type's immutability is to be checked.
 */
function checkNodeImmutability(program: ts.Program, node: ts.Node) {
  const typeNodeOrType = hasType(node)
    ? // Use the TypeNode if it's available.
      node.type
    : // Otherwise, get the Type from the checker.
      program.getTypeChecker().getTypeAtLocation(node);

  // Ensure a type was found before proceeding
  if (!typeNodeOrType) {
    console.log(`Could not determine type for node at position ${node.pos}.`);
    return;
  }

  const immutability = getTypeImmutability(program, typeNodeOrType);

  if (isUnknown(immutability)) {
    console.log(`Node at ${node.pos} has 'Unknown' immutability.`);
  } else if (isReadonlyDeep(immutability)) {
    console.log(`Node at ${node.pos} has 'ReadonlyDeep' or 'Immutable' immutability.`);
  } else if (immutability === Immutability.ReadonlyShallow) {
    console.log(`Node at ${node.pos} has 'ReadonlyShallow' immutability.`);
  } else if (immutability === Immutability.Mutable) {
    console.log(`Node at ${node.pos} has 'Mutable' immutability.`);
  } else {
    console.log(`Node at ${node.pos} has an unexpected immutability state.`);
  }
}

// Example usage within a dummy context (requires a real ts.Program and ts.Node)
// For a runnable example, you'd typically run this within an ESLint rule or custom TS transform.
// const dummyProgram = /* A real ts.Program instance */; 
// const dummyNode = /* A real ts.Node instance */; 
// if (dummyProgram && dummyNode) {
//   checkNodeImmutability(dummyProgram, dummyNode);
// } else {
//   console.log("Please provide a valid TypeScript program and node for this example.");
// }

view raw JSON →