CHAN.RUN
function declares<TArgs, TReturn, TErrors>(_errorClasses, fn): DeclaredFn<TArgs, TReturn, TErrors>;Defined in: src/declares.ts
Annotate a function's error surface — purely type-level, zero runtime cost.
const getUser = declares([NotFoundError, DatabaseError], async (id: string) => {
const row = await db.users.findById(id);
return ensure(row, NotFoundError, `No user: ${id}`);
});| Type Parameter |
|---|
TArgs extends unknown[] |
TReturn |
TErrors extends NamedFaultErrorClass<string>[] |
| Parameter | Type |
|---|---|
_errorClasses | [...TErrors[]] |
fn | (...args) => TReturn |
DeclaredFn<TArgs, TReturn, TErrors>
const NotFoundError = defineError("NotFoundError");
const DbError = defineError("DbError");
const getUser = declares([NotFoundError, DbError], async (id: string) => {
const row = await db.users.findById(id);
return ensure(row, NotFoundError, `No user: ${id}`);
});
// Callers using tryAsync get typed errors automatically:
const result = await tryAsync(getUser, "123");
if (!result.ok) {
result.error; // NotFoundError | DbError — not unknown
}const DbError = defineError("DbError");
export const userRepo = {
findById: declares([DbError], async (id: string) => {
return await db.query("SELECT * FROM users WHERE id = $1", [id]);
}),
create: declares([DbError], async (data: CreateUser) => {
return await db.query("INSERT INTO users ...", [data.name, data.email]);
}),
};const ApiError = defineError("ApiError");
const TimeoutError = defineError("TimeoutError");
const fetchProducts = declares([ApiError, TimeoutError], async (category: string) => {
const res = await fetch(`/api/products?category=${category}`);
if (!res.ok) fault(ApiError, `HTTP ${res.status}`);
return res.json() as Promise<Product[]>;
});