{"id":13171,"library":"factory.ts","title":"TypeScript Test Data Factory","description":"factory.ts is a TypeScript library designed for generating test data based on predefined interfaces or types, drawing inspiration from Ruby's `factory_bot` and JavaScript's `rosie`. As of its current stable version, 1.4.2, the library provides a robust, strongly-typed approach to creating data factories. Releases typically involve dependency updates and minor feature enhancements, as seen with recent additions like self-derived values and pipeline implementations. Its core differentiator lies in its deep integration with TypeScript, enabling type-safe factory definitions, sequence-number based value generation (`Factory.each`), and composition through factory extension and derived value functions (`withDerivationN`). This ensures that test data strictly adheres to the defined types, reducing runtime errors in test environments. It is primarily used as a development dependency for creating predictable and customizable test fixtures.","status":"active","version":"1.4.2","language":"javascript","source_language":"en","source_url":"https://github.com/willryan/factory.ts","tags":["javascript","typescript"],"install":[{"cmd":"npm install factory.ts","lang":"bash","label":"npm"},{"cmd":"yarn add factory.ts","lang":"bash","label":"yarn"},{"cmd":"pnpm add factory.ts","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"`factory.ts` exports its primary functionality as a namespace named `Factory`, which contains modules like `Sync` and `Async`, and helpers like `each`. Direct default imports will fail.","wrong":"import Factory from \"factory.ts\";","symbol":"Factory","correct":"import * as Factory from \"factory.ts\";"},{"note":"The `makeFactory` function for synchronous factories is located within the `Sync` module of the `Factory` namespace (`Factory.Sync.makeFactory`). It is not directly exported from the top-level package.","wrong":"import { makeFactory } from 'factory.ts';","symbol":"makeFactory","correct":"import * as Factory from \"factory.ts\"; Factory.Sync.makeFactory(...);"},{"note":"The `each` helper, used for sequence-based value generation, is directly available on the top-level `Factory` namespace for convenience. It can also be accessed via `Factory.Sync.each`.","wrong":"import { each } from 'factory.ts';","symbol":"each","correct":"import * as Factory from \"factory.ts\"; Factory.each(...);"}],"quickstart":{"code":"import * as Factory from \"factory.ts\";\n\ninterface Person {\n  id: number;\n  firstName: string;\n  lastName: string;\n  fullName: string;\n  age: number;\n}\n\n// Create a basic synchronous factory for the Person interface\nconst personFactory = Factory.Sync.makeFactory<Person>({\n  id: Factory.each((i) => i + 1), // Generate sequential IDs starting from 1\n  firstName: \"John\",\n  lastName: \"Doe\",\n  fullName: \"John Doe\", // Default full name\n  age: Factory.each((i) => 20 + (i % 10)), // Age cycles between 20 and 29\n});\n\n// Build a single person with default values\nconst defaultPerson = personFactory.build();\nconsole.log(\"Default Person:\", defaultPerson);\n// Example: { id: 1, firstName: 'John', lastName: 'Doe', fullName: 'John Doe', age: 20 }\n\n// Build a person overriding some properties\nconst janeSmith = personFactory.build({\n  firstName: \"Jane\",\n  lastName: \"Smith\"\n});\nconsole.log(\"Jane Smith (overridden):\", janeSmith);\n// Example: { id: 2, firstName: 'Jane', lastName: 'Smith', fullName: 'John Doe', age: 21 }\n\n// Build a list of people\nconst threePeople = personFactory.buildList(3, { lastName: \"Public\" });\nconsole.log(\"Three Publics:\", threePeople);\n/*\nExample: [\n  { id: 3, firstName: 'John', lastName: 'Public', fullName: 'John Doe', age: 22 },\n  { id: 4, firstName: 'John', lastName: 'Public', fullName: 'John Doe', age: 23 },\n  { id: 5, firstName: 'John', lastName: 'Public', fullName: 'John Doe', age: 24 }\n]\n*/\n\n// Demonstrate extending a factory for derived values\nconst autoFullNameFactory = personFactory.withDerivation2(\n  [\"firstName\", \"lastName\"],\n  \"fullName\",\n  (fName, lName) => `${fName} ${lName}`\n);\n\nconst derivedPerson = autoFullNameFactory.build({\n  firstName: \"Derived\",\n  lastName: \"Name\"\n});\nconsole.log(\"Derived Full Name Person:\", derivedPerson);\n// Example: { id: 1, firstName: 'Derived', lastName: 'Name', fullName: 'Derived Name', age: 20 }","lang":"typescript","description":"Demonstrates creating a synchronous factory, building single instances with overrides, generating lists, and extending a factory to derive properties from others."},"warnings":[{"fix":"Review existing factory definitions and test cases that involve setting `null` or `unknown` values on properties, ensuring they align with the new type behavior.","message":"The `RecPartial<>` generic type in `factory.ts` was updated in v1.2.0 to short-circuit on `unknown` types, preventing recursive checks into `unknown` properties. This change fixes issues where `null` or other primitives were incorrectly handled when attempting to set values for `unknown` properties.","severity":"breaking","affected_versions":">=1.2.0"},{"fix":"Ensure you call the correct `withDerivationN` function (e.g., `withDerivation2` for two dependencies) corresponding to the number of dependent keys provided.","message":"Derived values currently require using specific `withDerivation1` through `withDerivation5` methods, rather than a single overloaded `withDerivation` function. This is a TypeScript limitation that requires choosing the correct arity function (`withDerivationN`) based on the number of dependent properties.","severity":"gotcha","affected_versions":"*"},{"fix":"Prefer `import * as Factory from 'factory.ts';` for consistent behavior and full type support in TypeScript/ESM environments.","message":"While `factory.ts` includes TypeScript types, using CommonJS `require()` syntax (`const Factory = require('factory.ts');`) can lead to unexpected type issues or module resolution problems in modern TypeScript projects configured for ESM. The library is primarily designed for ESM consumption.","severity":"gotcha","affected_versions":"*"},{"fix":"Ensure `factory.ts` is listed under `devDependencies` in your `package.json`.","message":"This library is primarily intended for generating test data and should typically be installed as a `devDependency` (`npm install --save-dev factory.ts` or `yarn add -D factory.ts`). Including it as a production dependency unnecessarily increases bundle size and build times for deployable artifacts.","severity":"gotcha","affected_versions":"*"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Use a namespace import: `import * as Factory from 'factory.ts';`","cause":"Attempting to import `Factory` as a default export (`import Factory from 'factory.ts';`) when it is exported as a namespace.","error":"TypeError: (0, factory_ts_1.default) is not a function"},{"fix":"Access `makeFactory` via the `Sync` module: `Factory.Sync.makeFactory(...)`","cause":"Trying to access `makeFactory` directly on the `Factory` namespace, when it is nested under `Factory.Sync` (or `Factory.Async`).","error":"Property 'makeFactory' does not exist on type 'typeof import(\"factory.ts\")'."},{"fix":"Use the `withDerivationN` function that matches the number of dependent properties you are providing (e.g., `withDerivation2` for two dependencies).","cause":"Using the incorrect `withDerivationN` function (e.g., `withDerivation1`) for the number of dependent properties specified (e.g., two properties).","error":"Argument of type '(...)' is not assignable to parameter of type 'never'."}],"ecosystem":"npm","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":null,"cli_name":""}