{"id":17385,"library":"tmatch","title":"tmatch Deep Object Matching","description":"tmatch is a utility module designed to facilitate deep and flexible object matching, primarily used by the `t.match()` method in the `tap` test framework. Currently at version 5.0.0, it provides a comprehensive algorithm for comparing a target value against a pattern, supporting various data types including objects, arrays, regular expressions, dates, buffers, and constructor functions. Its matching logic goes beyond shallow equality, handling nested structures and specific type-based comparisons. For instance, it can match strings against regular expressions, check if an object is an `instanceof` a given constructor, or assert the absence of a property using `{propertyName: null}`. While its release cadence is tied to `tap`, it is generally stable. Key differentiators include its detailed, multi-step matching algorithm that accounts for many edge cases and its utility in robust assertion scenarios, offering a more nuanced comparison than standard deep equality checks.","status":"active","version":"5.0.0","language":"javascript","source_language":"en","source_url":"https://github.com/isaacs/tmatch","tags":["javascript"],"install":[{"cmd":"npm install tmatch","lang":"bash","label":"npm"},{"cmd":"yarn add tmatch","lang":"bash","label":"yarn"},{"cmd":"pnpm add tmatch","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"tmatch is exported as the default function for ESM consumers.","wrong":"import { tmatch } from 'tmatch';","symbol":"tmatch","correct":"import tmatch from 'tmatch';"},{"note":"For CommonJS, the module's export is the tmatch function directly.","wrong":"const { tmatch } = require('tmatch');","symbol":"tmatch","correct":"const tmatch = require('tmatch');"}],"quickstart":{"code":"const tmatch = require('tmatch');\n\n// Simulate an HTTP response object\nconst mockResponse = {\n  statusCode: 200,\n  headers: {\n    'content-type': 'application/json',\n    server: 'express/4.17.1'\n  },\n  body: {\n    message: 'Hello, world!'\n  }\n};\n\nconst expectedPattern = {\n  statusCode: 200,\n  headers: {\n    server: /express/, // Matches any server header containing 'express'\n    'content-type': 'application/json' // Exact string match\n  },\n  // 'body' property is not in pattern, so it's ignored during matching\n};\n\nif (tmatch(mockResponse, expectedPattern)) {\n  console.log('Response matches the expected pattern!');\n} else {\n  console.error('Response DOES NOT match the expected pattern.');\n  console.error('Actual:', JSON.stringify(mockResponse, null, 2));\n  console.error('Pattern:', JSON.stringify(expectedPattern, null, 2));\n}\n\n// Example of asserting a property's absence using null\nconst negativePattern = {\n  headers: {\n    'x-powered-by': null // Ensures 'x-powered-by' property is absent\n  }\n};\n\nconst responseWithXPoweredBy = {\n  statusCode: 200,\n  headers: {\n    'x-powered-by': 'Express',\n    server: 'express/4.17.1'\n  }\n};\n\nif (!tmatch(responseWithXPoweredBy, negativePattern)) {\n  console.log(\"Response does not have 'x-powered-by' header as expected (correct behavior for negative pattern).\");\n} else {\n  console.error(\"Response HAS 'x-powered-by' header, but pattern expected it absent.\");\n}","lang":"javascript","description":"Demonstrates `tmatch` for deep object comparison, including regex matching and asserting property absence with `null`."},"warnings":[{"fix":"If your intention is to ensure a property is missing, set its value in the pattern to `null` (e.g., `{ foo: null }`). If you want to match a property that exists and is `undefined`, use `{ foo: undefined }`.","message":"Using `undefined` in a pattern property will match an existing property explicitly set to `undefined`, not a missing property. To assert that a property is *absent* from the target object, use `null` in the pattern instead.","severity":"gotcha","affected_versions":">=5.0.0"},{"fix":"Be aware that patterns like `{ myValue: String }` will check `object.myValue instanceof String`, which is true for `new String('hi')` but false for `'hi'` (a string primitive). If you intend to match primitive types, specify the primitive value directly or use a `RegExp` for strings.","message":"When a pattern value is a `Function` constructor (e.g., `String`, `Array`, `Buffer`), `tmatch` checks if the corresponding object value is an `instanceof` that constructor. This differs from value-based comparison.","severity":"gotcha","affected_versions":">=5.0.0"},{"fix":"If strict equality is desired for non-object types or `null`/`undefined`, ensure the pattern and object values are explicitly identical, or use a custom matching function if `tmatch`'s specific loose equality behavior is not suitable.","message":"The algorithm's first step performs a loose equality check (`==`). This means `null` will match `undefined`, and some type coercions may occur before deeper comparison logic is applied. This can lead to unexpected matches if not accounted for.","severity":"gotcha","affected_versions":">=5.0.0"},{"fix":"For patterns requiring anything beyond simple substring presence, use a regular expression. For example, to match a string starting with 'prefix', use `{ myString: /^prefix/ }` instead of `{ myString: 'prefix' }`.","message":"String patterns are matched as substrings (step 6: 'return true if the string occurs within the object'). If you need more complex string matching (e.g., starts with, ends with), a `RegExp` pattern is required.","severity":"gotcha","affected_versions":">=5.0.0"}],"env_vars":null,"last_verified":"2026-04-22T00:00:00.000Z","next_check":"2026-07-21T00:00:00.000Z","problems":[{"fix":"Use a default import for ESM (`import tmatch from 'tmatch';`) or assign the direct module export for CommonJS (`const tmatch = require('tmatch');`).","cause":"Attempting to import `tmatch` as a named export (`import { tmatch } from 'tmatch'`) or destructure it from a CommonJS `require` call.","error":"TypeError: tmatch is not a function"},{"fix":"To assert that a property `foo` is completely absent from the target object, set its value in the pattern to `null`: `{ foo: null }`. `tmatch` resolves missing keys to `undefined` during comparison, allowing `null` to effectively act as a 'does not exist' assertion.","cause":"`tmatch` explicitly differentiates between an `undefined` value and a missing property. Using `undefined` in a pattern matches an existing property whose value is `undefined`.","error":"My pattern `{foo: undefined}` isn't matching objects without `foo`!"}],"ecosystem":"npm","meta_description":null}