Skip to content

Allow Transient Fields in defineTypeFactory #17

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Closed
mizdra opened this issue Aug 27, 2023 · 1 comment · Fixed by #20
Closed

Allow Transient Fields in defineTypeFactory #17

mizdra opened this issue Aug 27, 2023 · 1 comment · Fixed by #20
Labels
Status: Blocked Progress on the issue is Blocked Type: Change Change existing functionality.

Comments

@mizdra
Copy link
Owner

mizdra commented Aug 27, 2023

Problem

Currently, Transient Fields are only allowed in defineTypeFactoryWithTransientFields.

declare function defineAuthorFactoryWithTransientFields<
  _TransientFieldsResolver extends TransientFieldsResolver<Author, Record<string, unknown>>,
  TOptions extends AuthorFactoryDefineOptions<ResolvedFields<_TransientFieldsResolver>>,
>(
  transientFields: _TransientFieldsResolver,
  options: TOptions,
): AuthorFactoryInterface<ResolvedFields<_TransientFieldsResolver>, TOptions>;

const BookFactory = defineBookFactory({
  defaultFields: {
    id: lazy(({ seq }) => `Book-${seq}`),
    title: lazy(({ seq }) => `ゆゆ式 ${seq}巻`),
    author: undefined,
  },
});
const AuthorFactory = defineAuthorFactoryWithTransientFields(
  {
    bookCount: 0,
  },
  {
    defaultFields: {
      id: lazy(({ seq }) => `Author-${seq}`),
      name: '三上小又',
      books: lazy(async ({ get }) => {
        const bookCount = await get('bookCount');
        // eslint-disable-next-line max-nested-callbacks
        return Promise.all(Array.from({ length: bookCount }, async () => BookFactory.build()));
      }),
    },
  },
);

This confuses users as they have to use an unusual API. In addition, it is awkward to have to add one more argument.

Solution

I want defineTypeFactory to allow Transient Fields. The user specifies the type of Transient Fields using the type argument. Also, the default value of Transient Fields is specified by the defaultFields option.

declare function defineAuthorFactory<
  TransientFields extends Record<string, unknown>,
  TOptions extends AuthorFactoryDefineOptions<TransientFields>,
>(
  options: TOptions,
): AuthorFactoryInterface<TransientFields, TOptions>;

const BookFactory = defineBookFactory({
  defaultFields: {
    id: lazy(({ seq }) => `Book-${seq}`),
    title: lazy(({ seq }) => `ゆゆ式 ${seq}巻`),
    author: undefined,
  },
});
type BookTransientFields = {
  bookCount: number;
};
const AuthorFactory = defineAuthorFactory<BookTransientFields>({
  defaultFields: {
    id: lazy(({ seq }) => `Author-${seq}`),
    name: '三上小又',
    books: lazy(async ({ get }) => {
      const bookCount = await get('bookCount');
      // eslint-disable-next-line max-nested-callbacks
      return Promise.all(Array.from({ length: bookCount }, async () => BookFactory.build()));
    }),
    bookCount: 0,
  },
});

Additional context

As you can see from the sample code, defineTypeFactory currently has a type argument TOptions. This type argument is inferred from the type of the options argument. This allows the user to strictly type the return value of defineTypeFactory without having to specify the type argument.

However, it causes problems when TransientFields is added to the type arguments of defineTypeFactory. The user must explicitly pass the type TransientFields from the function caller, but then the type of the options argument is not inferred.

TypeScript does not support partial inference of type arguments. Therefore, an implementation of this feature is currently not possible. We will probably have to wait for the following issue to be resolved.

@mizdra mizdra added the Type: Add Add new features. label Aug 27, 2023
@mizdra mizdra mentioned this issue Aug 27, 2023
@mizdra mizdra added Status: Blocked Progress on the issue is Blocked Type: Change Change existing functionality. and removed Type: Add Add new features. labels Aug 27, 2023
@mizdra
Copy link
Owner Author

mizdra commented Aug 27, 2023

As a temporary workaround, defineAutorFactoryWithTransientFields can be defined by yourself: #20

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
Status: Blocked Progress on the issue is Blocked Type: Change Change existing functionality.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant