getSource()function
Recurse through Sourceable objects and return the first one that is an instance of type, or undefined if no source object matches.
getSource(type: Class<T>, value: unknown): T | undefined
Two helpers for traversing a chain of Sourceable objects — objects with a .source property — and returning the first instance of a given class. Used to unwrap layered or decorated objects back to their underlying implementation.
Things to know:
.source links recursively until it finds an instance of the requested class, or runs out of links.getSource() returns undefined when no matching instance is found; requireSource() throws RequiredError.Sourceable<T> interface (readonly source: T).import { getSource, requireSource } from "shelving/util";
import type { Sourceable } from "shelving/util";
class Database { query() { /* ... */ } }
class CachedDatabase implements Sourceable<Database> {
constructor(readonly source: Database) {}
}
class LoggedDatabase implements Sourceable<CachedDatabase> {
constructor(readonly source: CachedDatabase) {}
}
const db = new LoggedDatabase(new CachedDatabase(new Database()));
getSource(Database, db); // the inner Database instance
getSource(CachedDatabase, db); // the CachedDatabase instance
getSource(Database, {}); // undefined (no .source chain)
requireSource(Database, db); // the inner Database instance
requireSource(Database, "oops"); // throws RequiredErrorRecurse through Sourceable objects and return the first one that is an instance of type, or undefined if no source object matches.
getSource(type: Class<T>, value: unknown): T | undefined
Recurse through Sourceable objects and return the first one that is an instance of type, or throw RequiredError if no source object matches.
requireSource(type: Class<T>, data: unknown, caller: AnyCaller = requireSource): T
Something that has a source of a specified type.
{
readonly source: T;
}