Full Namespace
declare namespace Model {
/** Any type of Model, using own class constructor as its identifier. */
type Type<T extends Model = Model> = abstract new (...args: any[]) => T
/** A type of Model which may be created without constructor arguments. */
type New<T extends Model = Model> = (new () => T) & typeof Model;
/** Subset of `keyof T` which are not methods or defined by base Model U. **/
type Field<T> = Exclude<keyof T, keyof Model>;
type Key<T> = Field<T> | (string & {}) | number | symbol;
/** Actual value stored in state. */
type Actual<R> =
R extends Ref<infer T> ? T :
R extends Model ? State<R> :
R;
type Value<T extends Model, K extends Key<T>> =
K extends string | number | symbol ? T[K] extends Ref<infer V> ? V : T[K] : unknown;
type OnUpdate<T extends Model, K extends Key<T>> =
(this: T, value: Value<T, K>, key: K, thisArg: K) => void;
/**
* Values from current state of given controller.
* Differs from `Values` as values here will drill
* into "real" values held by exotics like ref.
*/
type State<T> = { [P in Field<T>]: Actual<T[P]> };
/** Object comparable to data found in T. */
type Values<T> = { [P in Field<T>]?: Actual<T[P]> };
/** Exotic value, where actual value is contained within. */
type Ref<T = any> = {
(next: T): void;
current: T | null;
}
/** A callback function which is subscribed to parent and updates when values change. */
type Effect<T> = (this: T, argument: T) => ((update: boolean | null) => void) | Promise<void> | null | void;
type Event<T extends Model> =
(this: T, key: unknown, source: T) => (() => void) | void | null;
namespace Instruction {
type Getter<T> = (source: Model) => T;
type Setter<T> = (value: T, previous: T) => boolean | void | (() => T);
type Descriptor<T = any> = {
get?: Getter<T> | boolean;
set?: Setter<T> | false;
enumerable?: boolean;
value?: T;
}
}
/**
* Property initializer, will run upon instance creation.
* Optional returned callback will run when once upon first access.
*/
type Instruction<T = any, M extends Model = any> =
// TODO: Should this allow for numbers/symbol properties?
(this: M, key: Model.Field<M> & string, thisArg: M, state: Model.State<M>) =>
Instruction.Descriptor<T> | Instruction.Getter<T> | void;
}
Type
Any type of Model, using own class constructor as its identifier.
type Type<T extends Model = Model> = abstract new (...args: any[]) => T;
New
A type of Model which may be created without constructor arguments.
type New<T extends Model = Model> = (new () => T) & typeof Model;
Field
Subset of keyof T
which are not methods or defined by base Model U.
type Field<T> = Exclude<keyof T, keyof Model>;
Key
Any acceptable event. This includes any field of T, for purposes of autocomplete, while string, number, and symbol are also valid.
type Key<T> = Field<T> | (string & {}) | number | symbol;
Actual
Actual value stored in state. This unwraps any exotic values like Ref whose value is not what is returned by its given property.
type Actual<R> = R extends Ref<infer T> ? T : R extends Model ? State<R> : R;
Value
Value of given key, unwrapping any exotic values like Ref whose value is not what is returned by its given property.
type Value<T extends Model, K extends Key<T>> =
K extends keyof T ? T[K] extends Ref<infer V> ? V : T[K] : unknown;