Skip to content
API/ListInput

ListInput

src/types/list-input.type.tstype

The input a list declares: what its request needs besides URL state.

type TaskListInput = ListInput<typeof taskList>; // { projectId: string }

never for a list that declares none, so [ListInput<TList>] extends [never] tells the two apart. It is also never for ListDefinition<ListParams>: through that type the requirement is erased, and buildListRequest() refuses a third argument. Generic code that holds a list that way carries the input itself, and forwards it by holding the list twice, loose and widened:

function buildRequestFor<TList extends ListDefinition<ListParams>>(
list: TList,
search: SearchParamsInput,
...args: [ListInput<TList>] extends [never] ? [] : [input: ListInput<TList>]
): ListRequest {
const loose: ListDefinition<ListParams> = list;
const wide: ListDefinition<ListParams, NonNullable<unknown>> = list;
const [input] = args;
const state = readListState(loose, search);
return input === undefined ? buildListRequest(loose, state) : buildListRequest(wide, state, input);
}

A list with an input never receives undefined, and a list without one always does, so the branch is exact. Both calls go through a copy: on the generic TList, readListState() returns the loose state, ParamsState<ListParams>, which buildListRequest() takes only with a list that is not generic.

The input is read from apply’s third parameter, not from the list’s type arguments, so it does not depend on how the list’s type is written: typeof list, an alias such as type LooseList = ListDefinition<ListParams>, an intersection and an object type written by hand all read the same. A list with no apply, or whose apply takes two parameters or an input of never, declares none.

type ListInput = conditional