runtime-branding
Version:
Runtime Branding API for TypeScript
63 lines (62 loc) • 2.62 kB
TypeScript
declare const brand: unique symbol;
interface Brand<B extends object> {
readonly [brand]: B;
}
/**
* Branded object type
*/
export declare type Branded<T, B extends object> = [T & Brand<B>][0];
declare type BrandedObject<B extends object, X extends object> = (object extends X ? [Brand<B>][0] : Branded<X, B>);
/**
* Branding function definition
*/
export interface Branding<B extends object, X extends object = object> extends Brand<B> {
/**
* Brands an object
* @param obj the object to brand
* @throws Error if the object is already branded
*/
<T extends X>(obj: T): Branded<T, B>;
/**
* Asserts this brand for the given object.
* @param obj the object to assert brand on
* @throws Error when object is not branded.
*/
assert(obj: object): asserts obj is BrandedObject<B, X>;
/**
* Checks if the given object has this brand.
* @param obj the object to check
*/
has(obj: object): obj is BrandedObject<B, X>;
/**
* Refines this branding with a new outer brand. The resulting branding will
* be a composition (merge) between the inner and outer brand.
* This method is actually a shortcut for createBranding and subsequent merge.
*
* @param newBrand the new brand that refines the current one
* @param callback a callback invoked when object are branded with the refined branding
*/
refine<N extends object, Y extends X = X>(newBrand: N, callback?: BrandingCallback<N, Y>): Branding<N & B, Y>;
/**
* Merges the given branding with the current one.
*
* @param branding the other brand to merge with
*/
merge<C extends object, Y extends X = X>(branding: Branding<C, Y>): Branding<B & C, Y>;
/**
* Returns this Branding with a different generic bound for target objects.
*/
generic<T extends object>(): Branding<B, T>;
}
/**
* A branding callback invoked during object branding
*/
export declare type BrandingCallback<B extends object, T extends object = object> = (obj: T, brand: B) => void;
/**
* Creates a new brand, identified by the provided branding object.
*
* @param brandObject An object that represents the brand. The shape of this object should be unique, and symbols may be used as unique keys.
* @param callback An optional callback with variable arguments which is invoked during object branding
*/
export declare function createBranding<B extends object, X extends object = object>(brandObject: B, callback?: BrandingCallback<B, X>): Branding<B, X>;
export {};