Skip to content

Support freezing states that contain typed arraysΒ #1190

@targos

Description

@targos

πŸš€ Feature Proposal

We would like that recursive freeze works when the state contains typed arrays.

We don't expect typed arrays to be draftable, but to be able to use them in the state managed by Immer (like a native Date for example).

Motivation

Before v11.0.0, the freeze function skipped non-draftable objects:

immer/src/utils/common.ts

Lines 210 to 211 in e1996ce

export function freeze<T>(obj: any, deep: boolean = false): T {
if (isFrozen(obj) || isDraft(obj) || !isDraftable(obj)) return obj

Now it's no the case anymore:

immer/src/utils/common.ts

Lines 245 to 246 in d6c1202

export function freeze<T>(obj: any, deep: boolean = false): T {
if (isFrozen(obj) || isDraft(obj)) return obj

The effect of the new behaviour with typed arrays is that now it throws an error because we are not allowed to call Object.freeze on them:

> require('immer').produce({test: new Uint8Array(10)}, (x) => x)
Uncaught TypeError: Cannot freeze array buffer views with elements
    at Object.freeze (<anonymous>)
    at freeze (/project/node_modules/immer/dist/cjs/immer.cjs.development.js:236:5)
    at /project/node_modules/immer/dist/cjs/immer.cjs.development.js:241:9

Can this be solved in user-land code?

I don't think so (except by disabling auto-freeze).

Example

import { produce } from 'immer';

const state = {
  data: new Uint8Array(10)
};

const newState = produce(state, (draft) => {
  draft.data = new Uint8Array(15);
});

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions