alexeyraspopov / dataclass

Data classes for TypeScript & JavaScript
https://dataclass.js.org
ISC License
181 stars 6 forks source link

Dataclass doesn't work in Jupyter notebook #16

Closed niobos closed 1 year ago

niobos commented 1 year ago

Hi,

First of all, thank you for your time and effort into making this project. I really appreciate that I'm able to stand on the shoulders of giants.

I'm trying to use Dataclass in a Jupyter/tslab notebook, but it fails:

import { Data } from "dataclass";

class Foo extends Data {
    name: string
    value: number
}

let a = Foo.create({name: "test", value: 42})

This gives the following output:

/private/tmp/jupyter-ts/node_modules/dataclass/dataclass.js:8
  O.freeze(O.assign(O.seal(O.assign(O.create(proto), base)), values));
             ^

TypeError: Cannot add property name, object is not extensible
    at Function.assign (<anonymous>)
    at produce (/private/tmp/jupyter-ts/node_modules/dataclass/dataclass.js:8:14)
    at Foo.create (/private/tmp/jupyter-ts/node_modules/dataclass/dataclass.js:12:12)
    at evalmachine.<anonymous>:8:13
    at evalmachine.<anonymous>:11:3
    at sigintHandlersWrap (node:vm:270:12)
    at Script.runInThisContext (node:vm:127:14)
    at Object.runInThisContext (node:vm:307:38)
    at Object.execute (/private/tmp/jupyter-ts/node_modules/tslab/dist/executor.js:162:38)
    at JupyterHandlerImpl.handleExecuteImpl (/private/tmp/jupyter-ts/node_modules/tslab/dist/jupyter.js:219:38)

I don't think this is an issue with dataclass itself, but I this seems like the most logical place to start. Feel free to point me to a better place to get help.

Regards,

niobos commented 1 year ago

Update: This does work with dataclass@2.0.0, but fails with dataclass@2.1.0 and 2.1.1

alexeyraspopov commented 1 year ago

@niobos, greetings!

Looking at the code example and error message, I feel like the root cause is lack of default values in class declaration. See Optional keys and code compilation caveat guide. I never used tslab and I am not sure what TS config it uses, but I assume your case can be solved by adding some default values to the properties:

import { Data } from "dataclass";

class Foo extends Data {
    name: string | null = null;
    value: number | null = null;
}

let a = Foo.create({name: "test", value: 42})
niobos commented 1 year ago

Hi @alexeyraspopov,

Thank you for getting back to me.

Your guess is correct, adding | null = null does make the error disappear. Using ?: does not solve the issue.

Thank you again for your time