0

I have got a object called curNode like this

{
    "name": "CAMPAIGN",
    "attributes": {},
    "children": []
}

I am trying to push to the object as shown below

curNode!.children!.push({
        name: newNodeName,
        children: [],
});

I get the below error

TypeError: Cannot add property 0, object is not extensible
    at Array.push (<anonymous>)
5
  • 2
    The array is frozen. Either don't freeze it if it's your code, or if it's not then most likely you sholdn't be mutating it. Commented Nov 10, 2022 at 11:43
  • Sorry may I know how not to freeze it. FYKI, I am calling curNode.children.push({}) during form submit. I am using formik forms Commented Nov 10, 2022 at 12:18
  • I tried console.log(Object.isExtensible(curNode)) and returns false. Wondering what could be done here. Commented Nov 10, 2022 at 19:35
  • I am using redux. Guess it has something to do with redux. Commented Nov 10, 2022 at 19:47
  • 1
    Don't mutate the object. That's the core philosophy of Redux, is it not? Treat the state as immutable. That's what you should be doing. Commented Nov 10, 2022 at 23:30

2 Answers 2

1

So in my case this post helped

Material-table TypeError: Cannot add property tableData, object is not extensible

As VLAZ mentioned, the object gets freezed, so I cloned the object using

const cloneData = structuredClone(object);

and everything started working.

Sign up to request clarification or add additional context in comments.

Comments

0

If you copy curNode to the TS playground, and hover over the type, you'll see its type is:

type T = {
    name: string;
    attributes: {};
    children: never[];
}

You can't add any elements to a never[] array.

In order to make the code work, you can declare a type and use it when you init curNode:

interface TNode {
    name?: string
    attributes?: object,
    children?: TNode[]
}

const curNode : TNode = {
    name: "CAMPAIGN",
    attributes: {},
    children: []
};

const newNodeName = "Foo"

curNode.children?.push({
    name: newNodeName,
    children: []
});

console.log(curNode);

// Output
//[LOG]: {
//  "name": "CAMPAIGN",
//  "attributes": {},
//  "children": [
//    {
//      "name": "Foo",
//      "children": []
//    }
//  ]
//} 

link to TS Playground


Edit:

Another option is to use new Array<any> instead of [] when initializing the array:

const curNode = {
    name: "CAMPAIGN",
    attributes: {},
    children: new Array<any>
};

const newNodeName = "Foo"

curNode.children?.push({
    name: newNodeName,
    children: []
});

console.log(curNode);

6 Comments

"You can't add any elements to a never[] array." this is not what the error means! The error is runtime because the array is immutable thus attempting to push results in TypeError. Demo. Open it in chrome to see the exact same message as in the question. FF will give a different one with the same meaning. You cannot mutate the frozen object. It is absolutely not a compiler error from TS. The only correct type change is to declare the objects as readonly to get compiler errors when trying to mutate them.
TypeScript infers the type of children as never[] and the compiler fails with an error if you try to push anything into an array of type never. Example here. See also: why-does-typescript-resolve-to-never.
The error from the compiler is not "TypeError: Cannot add property 0, object is not extensible". TypeError is a runtime JavaScript error. I've already supplied you with a demo of it. I don't know why you insist on the problem not being that. It's provably incorrect. The never[] issue is different and not related to what the question here asks. As I said - changing the type information will not solve the issue that the object is frozen at runtime. It is actively misleading as it does not reflect the immutability. See correct behaviour here: tsplay.dev/m0n1Rw
Hi, in the example in my comment above, we can see the JavaScript produced by the TypeScript compiler on the right side of the screen. It looks like this: const y = { a: [] };. We can see that a is not frozen. If we feed this code to a JavaScript interpreter, we can see that we can add and remove elements from a without any issues. Yes, I know we can't add elements to a frozen array, but TypeScript does not compile that array into a frozen JS array.
And I'm saying that you're wrong. Because OP gets a runtime error that only ever comes up if the object is frozen. I have already proven that the error reported in the question is that. Your example therefore does not match what the question describes. Proven by not getting a TypeError on running the code. I don't know why you are trying to convince me of something that is factually incorrect. None of your examples deal with the actual error that was reported. Are you trying to claim that the question asker does not get a TypeError and is lying to us? Can you prove it?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.