Type of the items.
Record of the extensions by key.
function bindGrid(source: IDataSourceWith<User, "filtering" | "pagination">) {
source.filtering.addFilter(adult); // guaranteed by the type
source.pagination.goToNextPage();
}
const users = createDataSource(readUsers, { filtering, pagination, sorting, distinct });
bindGrid(users); // more extensions than asked: fits
users.distinct; // DistinctExtension<User>, a custom key
users.on("items", (items) => render(items));
users.read().catch((error) => {
if (!isAbortedException(error)) throw error; // superseded: nothing to do
});
Reads items through a reader, letting its extensions shape the query and the result. See IDataSourceExtension for the read cycle.
Extensions in the type.
TExtis the record of the extensions of the source, by key (DataSourceExtensionsDefinition), the way the events of aSubscribableof ts-core are a record. Every key whose value cannot beundefinedis a required readonly property, every key whose value may beundefinedis an optional one, to narrow on; a key not in the record is not a property. The data source knows no key: the extensions of the package are named through IDataSourceWith (IDataSourceWith<User, "filtering" | "pagination">), the shortcut for the record of their interfaces. A source with more extensions is assignable to a parameter asking for fewer, never the opposite, and the default, an empty record, guarantees nothing. createDataSource infersTExtfrom the record it is given, custom keys included: no registration anywhere.This is a type alias, not an interface: TypeScript does not let an interface extend a mapped type over a generic record. Extend or implement it with concrete type arguments only; IDataSourceBase holds the members that do not depend on the extensions.
The latest read wins: a
read()requested while another is running supersedes it. The supersededread()rejects with theAbortedExceptionof ts-core at once, its result is discarded (noitems, noerror), anditemsalways hold the result of the latest completed read.