/** * The sentinel value returned by producers to replace the draft with undefined. */ declare const NOTHING: unique symbol; /** * To let Immer treat your class instances as plain immutable objects * (albeit with a custom prototype), you must define either an instance property * or a static property on each of your custom classes. * * Otherwise, your class instance will never be drafted, which means it won't be * safe to mutate in a produce callback. */ declare const DRAFTABLE: unique symbol; type AnyFunc = (...args: any[]) => any; type PrimitiveType = number | string | boolean; /** Object types that should never be mapped */ type AtomicObject = Function | Promise | Date | RegExp; /** * If the lib "ES2015.Collection" is not included in tsconfig.json, * types like ReadonlyArray, WeakMap etc. fall back to `any` (specified nowhere) * or `{}` (from the node types), in both cases entering an infinite recursion in * pattern matching type mappings * This type can be used to cast these types to `void` in these cases. */ type IfAvailable = true | false extends (T extends never ? true : false) ? Fallback : keyof T extends never ? Fallback : T; /** * These should also never be mapped but must be tested after regular Map and * Set */ type WeakReferences = IfAvailable> | IfAvailable>; type WritableDraft = { -readonly [K in keyof T]: Draft; }; /** Convert a readonly type into a mutable type, if possible */ type Draft = T extends PrimitiveType ? T : T extends AtomicObject ? T : T extends ReadonlyMap ? Map, Draft> : T extends ReadonlySet ? Set> : T extends WeakReferences ? T : T extends object ? WritableDraft : T; /** Convert a mutable type into a readonly type */ type Immutable = T extends PrimitiveType ? T : T extends AtomicObject ? T : T extends ReadonlyMap ? ReadonlyMap, Immutable> : T extends ReadonlySet ? ReadonlySet> : T extends WeakReferences ? T : T extends object ? { readonly [K in keyof T]: Immutable; } : T; interface Patch { op: "replace" | "remove" | "add"; path: (string | number)[]; value?: any; } type PatchListener = (patches: Patch[], inversePatches: Patch[]) => void; /** * Utility types */ type PatchesTuple = readonly [T, Patch[], Patch[]]; type ValidRecipeReturnType = State | void | undefined | (State extends undefined ? typeof NOTHING : never); type ReturnTypeWithPatchesIfNeeded = UsePatches extends true ? PatchesTuple : State; /** * Core Producer inference */ type InferRecipeFromCurried = Curried extends (base: infer State, ...rest: infer Args) => any ? ReturnType extends State ? (draft: Draft, ...rest: Args) => ValidRecipeReturnType> : never : never; type InferInitialStateFromCurried = Curried extends (base: infer State, ...rest: any[]) => any ? State : never; type InferCurriedFromRecipe = Recipe extends (draft: infer DraftState, ...args: infer RestArgs) => any ? ReturnType extends ValidRecipeReturnType ? (base: Immutable, ...args: RestArgs) => ReturnTypeWithPatchesIfNeeded : never : never; type InferCurriedFromInitialStateAndRecipe = Recipe extends (draft: Draft, ...rest: infer RestArgs) => ValidRecipeReturnType ? (base?: State | undefined, ...args: RestArgs) => ReturnTypeWithPatchesIfNeeded : never; /** * The `produce` function takes a value and a "recipe function" (whose * return value often depends on the base state). The recipe function is * free to mutate its first argument however it wants. All mutations are * only ever applied to a __copy__ of the base state. * * Pass only a function to create a "curried producer" which relieves you * from passing the recipe function every time. * * Only plain objects and arrays are made mutable. All other objects are * considered uncopyable. * * Note: This function is __bound__ to its `Immer` instance. * * @param {any} base - the initial state * @param {Function} producer - function that receives a proxy of the base state as first argument and which can be freely modified * @param {Function} patchListener - optional function that will be called with all the patches produced here * @returns {any} a new state, or the initial state if nothing was modified */ interface IProduce { /** Curried producer that infers the recipe from the curried output function (e.g. when passing to setState) */ (recipe: InferRecipeFromCurried, initialState?: InferInitialStateFromCurried): Curried; /** Curried producer that infers curried from the recipe */ (recipe: Recipe): InferCurriedFromRecipe; /** Curried producer that infers curried from the State generic, which is explicitly passed in. */ (recipe: (state: Draft, initialState: State) => ValidRecipeReturnType): (state?: State) => State; (recipe: (state: Draft, ...args: Args) => ValidRecipeReturnType, initialState: State): (state?: State, ...args: Args) => State; (recipe: (state: Draft) => ValidRecipeReturnType): (state: State) => State; (recipe: (state: Draft, ...args: Args) => ValidRecipeReturnType): (state: State, ...args: Args) => State; /** Curried producer with initial state, infers recipe from initial state */ (recipe: Recipe, initialState: State): InferCurriedFromInitialStateAndRecipe; /** Normal producer */ >(// By using a default inferred D, rather than Draft in the recipe, we can override it. base: Base, recipe: (draft: D) => ValidRecipeReturnType, listener?: PatchListener): Base; } /** * Like `produce`, but instead of just returning the new state, * a tuple is returned with [nextState, patches, inversePatches] * * Like produce, this function supports currying */ interface IProduceWithPatches { (recipe: Recipe): InferCurriedFromRecipe; (recipe: Recipe, initialState: State): InferCurriedFromInitialStateAndRecipe; >(base: Base, recipe: (draft: D) => ValidRecipeReturnType, listener?: PatchListener): PatchesTuple; } /** * The type for `recipe function` */ type Producer = (draft: Draft) => ValidRecipeReturnType>; type Objectish = AnyObject | AnyArray | AnyMap | AnySet; type AnyObject = { [key: string]: any; }; type AnyArray = Array; type AnySet = Set; type AnyMap = Map; /** Returns true if the given value is an Immer draft */ declare function isDraft(value: any): boolean; /** Returns true if the given value can be drafted by Immer */ declare function isDraftable(value: any): boolean; /** Get the underlying object that is represented by the given draft */ declare function original(value: T): T | undefined; /** * Freezes draftable objects. Returns the original object. * By default freezes shallowly, but if the second argument is `true` it will freeze recursively. * * @param obj * @param deep */ declare function freeze(obj: T, deep?: boolean): T; interface ProducersFns { produce: IProduce; produceWithPatches: IProduceWithPatches; } type StrictMode = boolean | "class_only"; declare class Immer implements ProducersFns { autoFreeze_: boolean; useStrictShallowCopy_: StrictMode; constructor(config?: { autoFreeze?: boolean; useStrictShallowCopy?: StrictMode; }); /** * The `produce` function takes a value and a "recipe function" (whose * return value often depends on the base state). The recipe function is * free to mutate its first argument however it wants. All mutations are * only ever applied to a __copy__ of the base state. * * Pass only a function to create a "curried producer" which relieves you * from passing the recipe function every time. * * Only plain objects and arrays are made mutable. All other objects are * considered uncopyable. * * Note: This function is __bound__ to its `Immer` instance. * * @param {any} base - the initial state * @param {Function} recipe - function that receives a proxy of the base state as first argument and which can be freely modified * @param {Function} patchListener - optional function that will be called with all the patches produced here * @returns {any} a new state, or the initial state if nothing was modified */ produce: IProduce; produceWithPatches: IProduceWithPatches; createDraft(base: T): Draft; finishDraft>(draft: D, patchListener?: PatchListener): D extends Draft ? T : never; /** * Pass true to automatically freeze all copies created by Immer. * * By default, auto-freezing is enabled. */ setAutoFreeze(value: boolean): void; /** * Pass true to enable strict shallow copy. * * By default, immer does not copy the object descriptors such as getter, setter and non-enumrable properties. */ setUseStrictShallowCopy(value: StrictMode): void; applyPatches(base: T, patches: readonly Patch[]): T; } /** Takes a snapshot of the current state of a draft and finalizes it (but without freezing). This is a great utility to print the current state during debugging (no Proxies in the way). The output of current can also be safely leaked outside the producer. */ declare function current(value: T): T; declare function enablePatches(): void; declare function enableMapSet(): void; /** * The `produce` function takes a value and a "recipe function" (whose * return value often depends on the base state). The recipe function is * free to mutate its first argument however it wants. All mutations are * only ever applied to a __copy__ of the base state. * * Pass only a function to create a "curried producer" which relieves you * from passing the recipe function every time. * * Only plain objects and arrays are made mutable. All other objects are * considered uncopyable. * * Note: This function is __bound__ to its `Immer` instance. * * @param {any} base - the initial state * @param {Function} producer - function that receives a proxy of the base state as first argument and which can be freely modified * @param {Function} patchListener - optional function that will be called with all the patches produced here * @returns {any} a new state, or the initial state if nothing was modified */ declare const produce: IProduce; /** * Like `produce`, but `produceWithPatches` always returns a tuple * [nextState, patches, inversePatches] (instead of just the next state) */ declare const produceWithPatches: IProduceWithPatches; /** * Pass true to automatically freeze all copies created by Immer. * * Always freeze by default, even in production mode */ declare const setAutoFreeze: (value: boolean) => void; /** * Pass true to enable strict shallow copy. * * By default, immer does not copy the object descriptors such as getter, setter and non-enumrable properties. */ declare const setUseStrictShallowCopy: (value: StrictMode) => void; /** * Apply an array of Immer patches to the first argument. * * This function is a producer, which means copy-on-write is in effect. */ declare const applyPatches: (base: T, patches: readonly Patch[]) => T; /** * Create an Immer draft from the given base state, which may be a draft itself. * The draft can be modified until you finalize it with the `finishDraft` function. */ declare const createDraft: (base: T) => Draft; /** * Finalize an Immer draft from a `createDraft` call, returning the base state * (if no changes were made) or a modified copy. The draft must *not* be * mutated afterwards. * * Pass a function as the 2nd argument to generate Immer patches based on the * changes that were made. */ declare const finishDraft: (draft: D, patchListener?: PatchListener | undefined) => D extends Draft ? T : never; /** * This function is actually a no-op, but can be used to cast an immutable type * to an draft type and make TypeScript happy * * @param value */ declare function castDraft(value: T): Draft; /** * This function is actually a no-op, but can be used to cast a mutable type * to an immutable type and make TypeScript happy * @param value */ declare function castImmutable(value: T): Immutable; export { Draft, Immer, Immutable, Objectish, Patch, PatchListener, Producer, StrictMode, WritableDraft, applyPatches, castDraft, castImmutable, createDraft, current, enableMapSet, enablePatches, finishDraft, freeze, DRAFTABLE as immerable, isDraft, isDraftable, NOTHING as nothing, original, produce, produceWithPatches, setAutoFreeze, setUseStrictShallowCopy };