{"id":12177,"library":"ts-interface-checker","title":"TypeScript Interface Runtime Validator","description":"ts-interface-checker is a runtime validation library for TypeScript interfaces, currently stable at version 1.0.2. It works in conjunction with `ts-interface-builder` (a build-time tool) to generate JavaScript modules that encapsulate the structural checks derived from TypeScript interface definitions. This approach allows developers to validate arbitrary JavaScript objects (e.g., parsed JSON from network requests or configuration files) against their TypeScript types at runtime, providing detailed error messages upon failure. The library itself is lightweight and focuses solely on the runtime checking mechanism, making it suitable for environments where type safety beyond compile-time is desired, such as API boundary validation. It supports checking properties, optional fields, and even method call arguments and return values as defined in interfaces. It maintains a stable release cadence for its core functionality.","status":"active","version":"1.0.2","language":"javascript","source_language":"en","source_url":"https://github.com/gristlabs/ts-interface-checker","tags":["javascript","typescript","ts","interface","type","validate","validator","check"],"install":[{"cmd":"npm install ts-interface-checker","lang":"bash","label":"npm"},{"cmd":"yarn add ts-interface-checker","lang":"bash","label":"yarn"},{"cmd":"pnpm add ts-interface-checker","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"This is the primary function for initializing checkers from generated type suites. The library is primarily ESM-first, so CommonJS `require` is not directly supported without a transpilation step or appropriate `esModuleInterop` configuration.","wrong":"const { createCheckers } = require('ts-interface-checker');","symbol":"createCheckers","correct":"import { createCheckers } from \"ts-interface-checker\";"},{"note":"Use this type to explicitly type the individual checker objects returned by `createCheckers` for enhanced type safety and IDE assistance.","symbol":"Checker","correct":"import type { Checker } from \"ts-interface-checker\";"},{"note":"Files generated by `ts-interface-builder` typically export a default object containing the type suite. Prefer default imports for these modules.","wrong":"import * as fooTI from \"./foo-ti\";","symbol":"Generated Type Suites (e.g., fooTI)","correct":"import fooTI from \"./foo-ti\";"}],"quickstart":{"code":"// 1. Define your TypeScript interface (e.g., in `foo.ts`)\n// interface Square {\n//   size: number;\n//   color?: string;\n// }\n\n// 2. Generate runtime checker code using ts-interface-builder (build step)\n//    npx ts-interface-builder foo.ts\n//    This creates `foo-ti.js` or `foo-ti.ts`.\n//    The content of `foo-ti.js` would look something like:\n/*\n// foo-ti.js\nimport * as t from \"ts-interface-checker\";\nexport const Square = t.iface([], {\n  \"size\": \"number\",\n  \"color\": t.opt(\"string\"),\n});\nconst exportedTypeSuite = { Square };\nexport default exportedTypeSuite;\n*/\n\n// 3. At runtime, import the generated type suite and create checkers.\n// For a self-contained example, we'll mock the `foo-ti` module content directly:\n\n// A minimal mock of what `foo-ti.js`'s default export would look like to `createCheckers`\n// In a real application, you would `import fooTI from './foo-ti';`\nconst mockFooTI = {\n  Square: { // This structure would be generated by ts-interface-builder\n    name: \"Square\",\n    check: (value: any) => {\n      if (typeof value !== 'object' || value === null) throw new Error('value is not an object');\n      if (typeof value.size !== 'number') throw new Error('value.size is not a number');\n      if ('color' in value && typeof value.color !== 'string') throw new Error('value.color is not a string');\n    }\n  }\n};\n\n// Import createCheckers from the library\nimport { createCheckers } from \"ts-interface-checker\";\n\nconst { Square } = createCheckers(mockFooTI); // Pass in the generated type suite\n\nconsole.log(\"Checking valid objects:\");\nSquare.check({ size: 1 });                  // OK\nSquare.check({ size: 1, color: \"green\" });  // OK\nconsole.log(\"Valid objects checked successfully.\");\n\ntry {\n  console.log(\"\\nChecking invalid object (missing property):\");\n  Square.check({ color: \"green\" });\n} catch (e: any) {\n  console.error(`Error: ${e.message}`); // Expected: Error: value.size is not a number\n}\n\ntry {\n  console.log(\"\\nChecking invalid object (wrong property type):\");\n  Square.check({ size: 4, color: 5 });\n} catch (e: any) {\n  console.error(`Error: ${e.message}`); // Expected: Error: value.color is not a string\n}","lang":"typescript","description":"Demonstrates the full workflow of defining a TypeScript interface, conceptually generating runtime checkers using `ts-interface-builder`, and then utilizing `ts-interface-checker` to validate JavaScript objects against the interface's structure at runtime, including expected error scenarios."},"warnings":[{"fix":"Ensure `npm install --save-dev ts-interface-builder` and `npm install --save ts-interface-checker` are executed, and run `npx ts-interface-builder <your-ts-files>` as part of your build process before runtime checks are performed.","message":"The `ts-interface-checker` package is a runtime dependency, but it requires definitions generated by `ts-interface-builder` at build-time. Users must install both, with `ts-interface-builder` as a dev dependency.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Avoid `strictCheck()` for interfaces that are part of public APIs or stable data contracts to allow for graceful schema evolution. Use standard `check()` unless strict enforcement of known properties is absolutely required.","message":"Using `strictCheck()` can lead to backward compatibility issues. If new optional properties are added to an interface, older code with `strictCheck()` will fail when validating data containing these new properties.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Refactor interfaces to avoid complex generics or manually implement runtime checks for parts of the schema that rely on unsupported generic constructs. Refer to `ts-interface-builder` limitations for details.","message":"The library does not currently support TypeScript generics (except for Promises, which are unwrapped). Interfaces with complex generic types will not be correctly processed by `ts-interface-builder`.","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 object being validated includes all non-optional properties defined in the TypeScript interface. For example, `Square.check({ size: 1 });` instead of `Square.check({ color: 'green' });` for an interface requiring `size`.","cause":"An object being checked against an interface is missing a required property.","error":"Error: value.size is missing"},{"fix":"Verify that all properties in the validated object conform to their specified TypeScript types. For example, `Square.check({ size: 4, color: 'blue' });` instead of `Square.check({ size: 4, color: 5 });`.","cause":"A property in the object being checked has an incorrect type according to the interface definition.","error":"Error: value.color is not a string"},{"fix":"Ensure arguments passed to `methodArgs().check()` match the types defined for the method's parameters in the interface. For example, `Greeter.methodArgs(\"greet\").check([\"Bob\"]);` instead of `Greeter.methodArgs(\"greet\").check([17]);`.","cause":"When validating method arguments, a parameter has an incorrect type.","error":"Error: value.name is not a string"},{"fix":"Provide all required arguments when calling `methodArgs().check()`. For example, `Greeter.methodArgs(\"greet\").check([\"Alice\"]);` instead of `Greeter.methodArgs(\"greet\").check([]);`.","cause":"When validating method arguments, a required parameter is missing from the argument list.","error":"Error: value.name is missing"},{"fix":"Ensure the return value passed to `methodResult().check()` matches the method's return type. For example, `Greeter.methodResult(\"greet\").check(\"hello\");` instead of `Greeter.methodResult(\"greet\").check(null);`.","cause":"When validating a method's return value, the value does not match the specified return type.","error":"Error: value is not a string"}],"ecosystem":"npm"}