alexeyraspopov / dataclass

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

Create data class without default values #18

Closed filantus closed 1 year ago

filantus commented 1 year ago

Hi, Alexey! Thank you for great lib!

Is there possible to create data class without default values?

Now if try that:

class User extends Data {
  name: string;
  age: number;  
}

const user = User.create({ name: "Evlampy", age: 20 });

Then got:

Uncaught (in promise) TypeError: Cannot add property name, object is not extensible

I know it's possible to define class with null values, but it's not same. The goal is don't define default values in class and prevent instantiating with empty values.

alexeyraspopov commented 1 year ago

Is there possible to create data class without default values?

Yes, but it requires making sure your TypeScript setup allows it. I described it here in the docs https://dataclass.js.org/guide/caveats.html#optional-keys-and-code-compilation

You have to consider ensure following: you're using tsc version 4.3.2 or higher and either your compile target is es2022 or useDefineForClassFields is set to true. You may find this flag being set to false if some dependencies in your system rely on the old behavior of class fields initialization. In any other case, optional properties are going to be missing completely and you won't be able to define them using create() method.

nickolay commented 1 year ago

the docs https://dataclass.js.org/guide/caveats.html#optional-keys-and-code-compilation

...seem to describe a way to define optional props:

class Entity extends Data {
  optionalProp?: string;
}

while the request here seems to ask for mandatory properties without defaults, as in https://github.com/alexeyraspopov/dataclass/issues/9

I see that in 2019 it was deemed impossible, but I don't understand the reasoning provided ("In JavaScript it's not possible because Babel removes class fields with no value"), as JS certainly supports class fields with no values and I can write what I want in TypeScript:

class User {
    name: string;
    age: number;
    constructor(name: string, age: number) {
        this.name = name;
        this.age = age;
    }
}
const u = new User("John", 21);

I was hoping dataclass would save me the constructor boilerplate in this case...