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").