typescriptreadonlytype-safetydataloader

Pass readonly parameter to mutable function (which will not mutate)


I need to create a function batchUsers which takes a readonly string as a parameter to create a DataLoader. In my batchUsers function I need to call a function (User.findby) which has defined its parameter not as readonly.

type BatchUser = (ids: readonly string[]) => Promise<User[]>;

const batchUsers:BatchUser = async (ids) => {
  const users = await User.findBy({ id: In(ids) });

  // reordering the users to match the ids
  const userMap: { [key: string]: User } = {};
  users.forEach((u) => {
    userMap[u.id] = u;
  })
  return ids.map((id) => userMap[id]);
}

export const userLoader = () => new DataLoader<string, User>(batchUsers)

Here I get the error: The type 'readonly string[]' is 'readonly' and cannot be assigned to the mutable type 'string[]' on thre ids in the findBy function

Alternatively if I set

type BatchUser = (ids: string[]) => Promise<User[]>;

Then I get the error:

Argument of type 'BatchUser' is not assignable to parameter of type 'BatchLoadFn<string, User>'.
  Types of parameters 'ids' and 'keys' are incompatible.
    The type 'readonly string[]' is 'readonly' and cannot be assigned to the mutable type 'string[]'

in the last line where I create the new Dataloader

How can I avoid this?


Solution

  • The only way I found to make this work leand on the suggestion of caTS and does:

    const users = await User.findBy({ id: In(ids as string[]) });
    

    instead of

    const users = await User.findBy({ id: In(ids) });