Defining Placeholders
When defining dependent properties or variables, you cannot reference other properties or variables within .define
, so sometimes you may want to set placeholder values. In such cases, you can use later
to define only the type, setting the actual value later.
import { factory, later } from "@factory-js/factory";
const userFactory = factory
.define({
props: {
firstName: () => "John",
lastName: () => "Doe",
// Define only the type to allow TypeScript to infer it, and set the actual value later
fullName: later<string>(),
},
vars: {},
})
.props({
// Set the value of `fullName` here
fullName: async ({ props }) =>
`${await props.firstName} ${await props.lastName}`,
});
If you use this factory without setting the value of this property later, later
will throw an exception. This way, you can catch mistakes if you forget to set the value.
import { factory, later } from "@factory-js/factory";
const userFactory = factory.define({
props: {
firstName: () => "John",
lastName: () => "Doe",
fullName: later<string>(),
},
vars: {},
});
userFactory.build(); // ❌ Throws an exception because `fullName` is not set
Defining Properties Without Default Values
Another use of later
is to define properties without default values. In the example below, the type
property is defined with later
.
factories/item-factory.ts
import { factory, later } from "@factory-js/factory";
export const itemFactory = factory.define({
props: {
type: later<"book" | "food">(),
price: () => 0,
},
vars: {},
});
By defining properties this way, you ensure that values must be set in advance using .props
when creating objects with the factory. Otherwise, an exception will be thrown.
import { expect, it, describe } from "vitest";
import { itemFactory } from "../factories/item-factory";
import { isFood } from "./is-food";
describe("when the type is food", () => {
it("returns true", async () => {
// ✅ No exception is thrown because `type` is set
const item = await itemFactory.props({ type: () => "food" }).build();
expect(isFood(item)).toBe(true);
});
});
describe("when the type is book", () => {
it("returns false", async () => {
// ❌ Throws an exception because `type` is not set
const item = await itemFactory.build();
expect(isFood(item)).toBe(false);
});
});