UNPKG

mobx-keystone

Version:

A MobX powered state management solution based on data trees with first class support for TypeScript, snapshots, patches and much more

188 lines (187 loc) 8.08 kB
import { SnapshotInOf, SnapshotOutOf } from '../snapshot/SnapshotOf'; import { LateTypeChecker, TypeChecker } from '../types/TypeChecker'; import { Flatten, IsNeverType, IsOptionalValue } from '../utils/types'; /** * @ignore */ export declare const noDefaultValue: unique symbol; /** * A model property. */ export interface ModelProp<TPropValue, TPropCreationValue, TTransformedValue, TTransformedCreationValue, TIsRequired, TIsId extends boolean = false, THasSetter = never, TFromSnapshotOverride = never, TToSnapshotOverride = never> { $valueType: TPropValue; $creationValueType: TPropCreationValue; $transformedValueType: TTransformedValue; $transformedCreationValueType: TTransformedCreationValue; $isRequired: TIsRequired; $isId: TIsId; $hasSetter: THasSetter; $fromSnapshotOverride: TFromSnapshotOverride; $toSnapshotOverride: TToSnapshotOverride; _defaultFn: (() => TPropValue) | typeof noDefaultValue; _defaultValue: TPropValue | typeof noDefaultValue; _typeChecker: TypeChecker | LateTypeChecker | undefined; _setter: boolean | "assign"; _isId: boolean; _transform: { transform: (original: unknown, model: object, propName: PropertyKey, setOriginalValue: (newOriginalValue: unknown) => void) => unknown; untransform: (transformed: unknown, model: object, propName: PropertyKey) => unknown; } | undefined; _fromSnapshotProcessor?: (sn: unknown) => unknown; _toSnapshotProcessor?: (sn: unknown) => unknown; withSetter(): ModelProp<TPropValue, TPropCreationValue, TTransformedValue, TTransformedCreationValue, TIsRequired, TIsId, string, TFromSnapshotOverride, TToSnapshotOverride>; /** * @deprecated Setter methods are preferred. */ withSetter(mode: "assign"): ModelProp<TPropValue, TPropCreationValue, TTransformedValue, TTransformedCreationValue, TIsRequired, TIsId, string, TFromSnapshotOverride, TToSnapshotOverride>; /** * Sets a transform for the property instance value. * * @template TTV Transformed value type. * @param transform Transform to be used. * @returns */ withTransform<TTV>(transform: ModelPropTransform<NonNullable<TPropValue>, TTV>): ModelProp<TPropValue, TPropCreationValue, TTV | Extract<TPropValue, null | undefined>, TTV | Extract<TPropCreationValue, null | undefined>, TIsRequired, TIsId, THasSetter, TFromSnapshotOverride, TToSnapshotOverride>; withSnapshotProcessor<FS = TFromSnapshotOverride, TS = TToSnapshotOverride, This extends AnyModelProp = this>(processor: { fromSnapshot?: (sn: FS) => ModelPropFromSnapshot<This>; toSnapshot?: (sn: ModelPropToSnapshot<This>) => TS; }): ModelProp<TPropValue, TPropCreationValue, TTransformedValue, TTransformedCreationValue, TIsRequired, TIsId, THasSetter, FS, TS>; } /** * The snapshot in type of a model property. */ export type ModelPropFromSnapshot<MP extends AnyModelProp> = IsNeverType<MP["$fromSnapshotOverride"], SnapshotInOf<MP["$creationValueType"]>, MP["$fromSnapshotOverride"]>; /** * The snapshot out type of a model property. */ export type ModelPropToSnapshot<MP extends AnyModelProp> = IsNeverType<MP["$toSnapshotOverride"], SnapshotOutOf<MP["$valueType"]>, MP["$toSnapshotOverride"]>; /** * A model prop transform. */ export interface ModelPropTransform<TOriginal, TTransformed> { transform(params: { originalValue: TOriginal; cachedTransformedValue: TTransformed | undefined; setOriginalValue(value: TOriginal): void; }): TTransformed; untransform(params: { transformedValue: TTransformed; cacheTransformedValue: () => void; }): TOriginal; } /** * Any model property. */ export type AnyModelProp = ModelProp<any, any, any, any, any, any, any, any, any>; /** * Model properties. */ export interface ModelProps { [k: string]: AnyModelProp; } export type RequiredModelProps<MP extends ModelProps> = { [K in keyof MP]: MP[K]["$isRequired"] & K; }[keyof MP]; export type ModelPropsToUntransformedData<MP extends ModelProps> = Flatten<{ [k in keyof MP]: MP[k]["$valueType"]; }>; export type ModelPropsToSnapshotData<MP extends ModelProps> = Flatten<{ [k in keyof MP]: ModelPropToSnapshot<MP[k]> extends infer R ? R : never; }>; export type ModelPropsToUntransformedCreationData<MP extends ModelProps> = { [k in keyof MP]?: MP[k]["$creationValueType"]; } & { [k in RequiredModelProps<MP>]: MP[k]["$creationValueType"]; }; export type ModelPropsToSnapshotCreationData<MP extends ModelProps> = Flatten<{ [k in keyof MP]?: ModelPropFromSnapshot<MP[k]> extends infer R ? R : never; } & { [k in { [K in keyof MP]: IsNeverType<MP[K]["$fromSnapshotOverride"], MP[K]["$isRequired"] & K, // no override IsOptionalValue<MP[K]["$fromSnapshotOverride"], never, K>>; }[keyof MP]]: ModelPropFromSnapshot<MP[k]> extends infer R ? R : never; }>; export type ModelPropsToTransformedData<MP extends ModelProps> = Flatten<{ [k in keyof MP]: MP[k]["$transformedValueType"]; }>; export type ModelPropsToTransformedCreationData<MP extends ModelProps> = { [k in keyof MP]?: MP[k]["$transformedCreationValueType"]; } & { [k in RequiredModelProps<MP>]: MP[k]["$transformedCreationValueType"]; }; export type ModelPropsToSetter<MP extends ModelProps> = Flatten<{ [k in keyof MP as MP[k]["$hasSetter"] & `set${Capitalize<k & string>}`]: (value: MP[k]["$transformedValueType"]) => void; }>; export type ModelIdProp<T extends string = string> = ModelProp<T, T | undefined, T, T | undefined, never, // not required true>; /** * A property that will be used as model id, accessible through $modelId. * Can only be used in models and there can be only one per model. */ export declare const idProp: ModelIdProp & { /** * Same as `idProp`, except that it might have an specific TypeScript string template as type. * E.g. `typedIdProp<`custom-${string}`>()` */ typedAs<T extends string>(): ModelIdProp<T>; }; /** * @ignore */ export type OnlyPrimitives<T> = Exclude<T, object>; /** * A model prop that maybe / maybe not is optional, depending on if the value can take undefined. */ export type MaybeOptionalModelProp<TPropValue> = ModelProp<TPropValue, TPropValue, TPropValue, TPropValue, IsOptionalValue<TPropValue, never, string>>; /** * A model prop that is definitely optional. */ export type OptionalModelProp<TPropValue> = ModelProp<TPropValue, TPropValue | null | undefined, TPropValue, TPropValue | null | undefined, never>; /** * Defines a model property, with an optional function to generate a default value * if the input snapshot / model creation data is `null` or `undefined`. * * Example: * ```ts * x: prop(() => 10) // an optional number, with a default value of 10 * x: prop<number[]>(() => []) // an optional number array, with a default empty array * ``` * * @template TValue Value type. * @param defaultFn Default value generator function. * @returns */ export declare function prop<TValue>(defaultFn: () => TValue): OptionalModelProp<TValue>; /** * Defines a model property, with an optional default value * if the input snapshot / model creation data is `null` or `undefined`. * You should only use this with primitive values and never with object values * (array, model, object, etc). * * Example: * ```ts * x: prop(10) // an optional number, with a default value of 10 * ``` * * @template TValue Value type. * @param defaultValue Default primitive value. * @returns */ export declare function prop<TValue>(defaultValue: OnlyPrimitives<TValue>): OptionalModelProp<TValue>; /** * Defines a model property with no default value. * * Example: * ```ts * x: prop<number>() // a required number * x: prop<number | undefined>() // an optional number, which defaults to undefined * ``` * * @template TValue Value type. * @returns */ export declare function prop<TValue>(): MaybeOptionalModelProp<TValue>; /** * @ignore */ export declare function getModelPropDefaultValue(propData: AnyModelProp): unknown | typeof noDefaultValue;