Home > Blockchain >  Why would structuredClone() ignore properties?
Why would structuredClone() ignore properties?

Time:01-25

In a TypeScript web project I am using structuredClone to deep-clone an AxiosError object from the Axios library, defined as:

export interface AxiosError<T = any> extends Error {
  //...
  isAxiosError: boolean;
  toJSON: () => object;
}

interface Error {
    name: string;
    // ...
}

My code:

function f(axiosError: AxiosError<ArrayBuffer>): void {
  const copy = window.structuredClone(axiosError);
  const a = typeof axiosError.name === "undefined";         // false
  const b = typeof axiosError.isAxiosError === "undefined"; // false
  const c = typeof copy.name === "undefined";               // false
  const d = typeof copy.isAxiosError === "undefined";       // true
}

Upon further investigation, it appears that all of the parent properties are cloned, but the child properties are not. Why? I can reproduce this in Firefox and Chrome.

CodePudding user response:

If you're asking why your sub-classed AxiosError only contains the default properties of the parent Error class, that's by design.

structuredClone is meant to be used to send data across realms. The receiving realm may have no clue about your AwesomeError class, and so the object is normalized to what all realms will know about, here an Error, but the same applies to other cloneable interfaces like Set, Map etc.

So indeed, if you stucture clone an instance of a subclass of Error, all you get are the default properties of Error.

Note that there is this issue which aims to at least make .name be treated exceptionally in the cloning algo, but it still requires implementers interest (read, "it's not done yet").

  • Related