Caveats 
In the world of always changing tooling and evolving specs, it is hard to avoid weird edge cases that can lead to hours of wasted time. On this page you may find some known caveats and potential issues when using data classes, and possible ways to resolve or avoid them.
Optional keys and code compilation 
Defining a data class you may find yourself in a situation where a property doesn't have a reasonable default value. Actual value may be provided during instantiation or the property's value can be treated as missing.
The most universal approach (i.e. works in any environment for both TypeScript and Flowtype) going to be the use of null as default value:
class Entity extends Data {
  optionalProp: string | null = null;
}
let entity = Entity.create();
// > Entity { optionalProp: null }
let payload = JSON.stringify(entity);
// > { "optionalProp": null }When using TypeScript, you may want to use optional parameters instead of nullable types, as a less noisy syntax:
class Entity extends Data {
  optionalProp?: string;
}
let entity = Entity.create();
// > Entity { optionalProp: undefined }When doing so, 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.
Warning: During serialization, undefined values do not appear in resulting JSON string:
class Entity extends Data {
  optionalProp?: string;
}
let entity = Entity.create();
// > Entity { optionalProp: undefined }
let payload = JSON.stringify(entity);
// > {}When using Flowtype, it is preferable to stick to nullable types with null explicitly set as default value. Basic Flowtype plugins for Babel going to strip out typings including properties themselves.
class Entity extends Data {
  optionalProp: ?string = null;
}
let entity = Entity.create();
// > Entity { optionalProp: null }
let payload = JSON.stringify(entity);
// > { "optionalProp": null }Explicit this signature in methods 
When using TypeScript, whenever a data class contains a method, that uses this.copy() or this.equals(), you may see a typing error. But you have done nothing wrong. There are some limitations in TypeScript or this library's typings, but that's something you can easily fix:
class Entity extends Data {
  counter: number = 13;
  // set explicit this type to a method that uses other data class methods
  increment(this: Entity) {
    return this.copy({ counter: this.counter + 1 })
  }
}
let entity = Entity.create({ counter: 10 });
// > Entity { counter: 10 }
let updated = entity.increment();
// > Entity { counter: 11 }