{"id":12122,"library":"tcomb","title":"tcomb: Runtime Type Checking & DDD","description":"tcomb is a JavaScript library for runtime type checking and Domain-Driven Design (DDD), suitable for both Node.js and browser environments. It provides a concise syntax for defining and validating data structures, enhancing code safety during development. The current stable version is 3.2.29, with a recent cadence focused on bug fixes and TypeScript definition improvements. A key differentiator is its lightweight nature (3KB gzipped, no dependencies) and its foundation in set theory for type definition. It supports various type combinators (structs, lists, enums, refinements, unions), immutability helpers compatible with Facebook's Immutability Helpers, and runtime type introspection. Crucially, tcomb is designed to be *disabled in production* (its checks are stripped out for performance), with `io-ts` or `tcomb-validation` recommended for production-grade type validation.","status":"active","version":"3.2.29","language":"javascript","source_language":"en","source_url":"https://github.com/gcanti/tcomb","tags":["javascript","type","combinators","checking","safety","model","domain","debugging","immutable","typescript"],"install":[{"cmd":"npm install tcomb","lang":"bash","label":"npm"},{"cmd":"yarn add tcomb","lang":"bash","label":"yarn"},{"cmd":"pnpm add tcomb","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"The default export `t` is the primary entry point, providing access to all type combinators (e.g., `t.Number`, `t.struct`) and utilities like `t.update`. The CommonJS `require` syntax is typically considered outdated in modern JavaScript projects unless explicitly targeting older Node.js environments.","wrong":"const t = require('tcomb');","symbol":"t (default export)","correct":"import t from 'tcomb';"},{"note":"While tcomb ships with TypeScript definitions, its types are typically accessed via the `t` object itself (e.g., `t.String`, `t.struct`). For defining types, you'd usually import `t` and use its properties or leverage `t.TypeOf<typeof ...>` for inference.","symbol":"Type definitions (TypeScript)","correct":"import t from 'tcomb';\n// Or for type inference:\ntype MyStructType = t.TypeOf<typeof MyStructDefinition>;"},{"note":"Individual type combinators and utilities like `struct`, `list`, `maybe`, `update` are properties of the `t` object, not direct named exports. Attempting to destructure them directly will result in an `undefined` value or a runtime error.","wrong":"import { struct } from 'tcomb';","symbol":"Specific combinator (e.g., struct)","correct":"import t from 'tcomb';\nconst MyType = t.struct({ /* ... */ });"}],"quickstart":{"code":"import t from 'tcomb';\n\n// A type-checked function demonstrating basic validation\nfunction sum(a, b) {\n  t.Number(a); // Runtime check: 'a' must be a Number\n  t.Number(b); // Runtime check: 'b' must be a Number\n  return a + b;\n}\n\ntry {\n  sum(1, 's'); // This will throw an error\n} catch (e) {\n  console.error(`Caught error for sum(1, 's'): ${e.message}`);\n}\n\n// Define a custom refined type (Integer)\nconst Integer = t.refinement(t.Number, (n) => n % 1 === 0, 'Integer');\n\n// Define a structured object (a 'struct') for a Person\nconst Person = t.struct({\n  name: t.String,              // required string\n  surname: t.maybe(t.String),  // optional string (can be null or undefined)\n  age: Integer,                // required integer (using our custom Integer type)\n  tags: t.list(t.String)       // a list of strings\n}, 'Person');\n\n// Add a method to the struct's prototype (as you would with a class)\nPerson.prototype.getFullName = function () {\n  return `${this.name} ${this.surname ?? ''}`.trim();\n};\n\nlet personInstance;\ntry {\n  personInstance = Person({\n    name: 'Guido',\n    age: 42,\n    tags: ['developer', 'js']\n  });\n  console.log(`Created person: ${personInstance.getFullName()}`);\n} catch (e) {\n  console.error(`Caught error creating person: ${e.message}`);\n}\n\n// Attempt to create a person with missing required fields\ntry {\n  Person({\n    surname: 'Canti'\n  }); // This will throw an error for missing 'name' and 'age'\n} catch (e) {\n  console.error(`Caught error for invalid person creation: ${e.message}`);\n}\n\n// Update an immutable instance using t.update\nconst updatedPerson = Person.update(personInstance, {\n  name: { $set: 'Giuliano' }, // Change name\n  age: { $set: 43 },          // Change age\n  tags: { $push: ['opensource'] } // Add a tag\n});\nconsole.log(`Updated person: ${updatedPerson.getFullName()}, Age: ${updatedPerson.age}, Tags: ${updatedPerson.tags.join(', ')}`);","lang":"javascript","description":"This quickstart demonstrates how to define type-checked functions, create custom refined types, build structured objects (structs) with runtime validation, and perform immutable updates on instances using tcomb's utilities."},"warnings":[{"fix":"For production-grade runtime type validation, consider using alternative libraries from the same author, such as `io-ts` or `tcomb-validation`. Do not deploy tcomb-dependent code to production expecting runtime checks to be active.","message":"tcomb is explicitly designed to be disabled in production environments. All type checks and `Object.freeze` calls are stripped out when `process.env.NODE_ENV` is set to `'production'`, rendering it ineffective for production validation and potentially leading to unexpected behavior if relied upon.","severity":"breaking","affected_versions":">=1.0.0"},{"fix":"Ensure you understand the distinction between compile-time TypeScript validation and tcomb's runtime validation. For automatic runtime checks based on type annotations, consider integrating `babel-plugin-tcomb` into your build process.","message":"While tcomb ships with TypeScript definitions, its runtime checks are distinct from compile-time TypeScript checks. Using `babel-plugin-tcomb` allows for a more integrated experience with type annotations, but without it, runtime checks must be explicitly called (e.g., `t.Number(a)`).","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Use the `t.update(instance, spec)` utility with immutability helpers (`$set`, `$merge`, `$push`, etc.) to create new instances with desired modifications, rather than attempting to mutate the original instance.","message":"Instances created with tcomb structs are immutable by default via `Object.freeze` in development. Direct modification attempts on these objects will fail silently in non-strict mode or throw errors in strict mode.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Ensure the value passed to the tcomb type check (e.g., `t.Number(value)`) matches the expected type. In TypeScript, this might indicate a mismatch between static and runtime types.","cause":"Attempting to pass a value of an incorrect type (e.g., a string) to a tcomb type checker that expects a different type (e.g., Number).","error":"[tcomb] Invalid value \"s\" supplied to Number"},{"fix":"Provide a valid value for all required fields in the struct's constructor. For fields that can be `null` or `undefined`, define them using `t.maybe(Type)`.","cause":"A required field in a tcomb struct was omitted or explicitly supplied with `undefined` when a non-optional type (e.g., `t.String` instead of `t.maybe(t.String)`) was expected.","error":"[tcomb] Invalid value undefined supplied to Person/name: String"}],"ecosystem":"npm"}