Skip to main content

Nullable object vs non-nullable

Emi definition allows for nullable object vs non-nullable objects. In case an object is not nullable, should always be present and initialised by the parent class upon instantiation. For types, simply it would indicate that it needs to be present.

name: nullableResponseAction
fields:
- name: mother
type: object
description: Mother info should be present
fields:
- name: firstName
type: string
- name: father
type: object?
description: Father name is not essential for some goverment papers.
fields:
- name: firstName
type: string
- name: firstUncle
type: one
target: UncleDto
description: Uncle is a separate dto, therefor we use that entity
- name: secondUncle
type: one?
target: UncleDto
description: Second uncle is optional

import { UncleDto } from "./UncleDto";
import { withPrefix } from "./sdk/common/withPrefix";
/**
* The base class definition for nullableResponseActionDto
**/
export class NullableResponseActionDto {
/**
* Mother info should be present
* @type {NullableResponseActionDto.Mother}
**/
#mother!: InstanceType<typeof NullableResponseActionDto.Mother>;
/**
* Mother info should be present
* @returns {NullableResponseActionDto.Mother}
**/
get mother() {
return this.#mother;
}
/**
* Mother info should be present
* @type {NullableResponseActionDto.Mother}
**/
set mother(value: InstanceType<typeof NullableResponseActionDto.Mother>) {
// For objects, the sub type needs to always be instance of the sub class.
if (value instanceof NullableResponseActionDto.Mother) {
this.#mother = value;
} else {
this.#mother = new NullableResponseActionDto.Mother(value);
}
}
setMother(value: InstanceType<typeof NullableResponseActionDto.Mother>) {
this.mother = value;
return this;
}
/**
* Father name is not essential for some goverment papers.
* @type {NullableResponseActionDto.Father}
**/
#father?:
| InstanceType<typeof NullableResponseActionDto.Father>
| null
| undefined
| null = undefined;
/**
* Father name is not essential for some goverment papers.
* @returns {NullableResponseActionDto.Father}
**/
get father() {
return this.#father;
}
/**
* Father name is not essential for some goverment papers.
* @type {NullableResponseActionDto.Father}
**/
set father(
value:
| InstanceType<typeof NullableResponseActionDto.Father>
| null
| undefined
| null
| undefined,
) {
// For objects, the sub type needs to always be instance of the sub class.
if (value instanceof NullableResponseActionDto.Father) {
this.#father = value;
} else {
this.#father = new NullableResponseActionDto.Father(value);
}
}
setFather(
value:
| InstanceType<typeof NullableResponseActionDto.Father>
| null
| undefined
| null
| undefined,
) {
this.father = value;
return this;
}
/**
* Uncle is a separate dto, therefor we use that entity
* @type {UncleDto}
**/
#firstUncle!: UncleDto;
/**
* Uncle is a separate dto, therefor we use that entity
* @returns {UncleDto}
**/
get firstUncle() {
return this.#firstUncle;
}
/**
* Uncle is a separate dto, therefor we use that entity
* @type {UncleDto}
**/
set firstUncle(value: UncleDto) {
// For objects, the sub type needs to always be instance of the sub class.
if (value instanceof UncleDto) {
this.#firstUncle = value;
} else {
this.#firstUncle = new UncleDto(value);
}
}
setFirstUncle(value: UncleDto) {
this.firstUncle = value;
return this;
}
/**
* Second uncle is optional
* @type {UncleDto}
**/
#secondUncle?: UncleDto | null = undefined;
/**
* Second uncle is optional
* @returns {UncleDto}
**/
get secondUncle() {
return this.#secondUncle;
}
/**
* Second uncle is optional
* @type {UncleDto}
**/
set secondUncle(value: UncleDto | null | undefined) {
// For objects, the sub type needs to always be instance of the sub class.
if (value instanceof UncleDto) {
this.#secondUncle = value;
} else {
this.#secondUncle = new UncleDto(value);
}
}
setSecondUncle(value: UncleDto | null | undefined) {
this.secondUncle = value;
return this;
}
/**
* The base class definition for mother
**/
static Mother = class Mother {
/**
*
* @type {string}
**/
#firstName: string = "";
/**
*
* @returns {string}
**/
get firstName() {
return this.#firstName;
}
/**
*
* @type {string}
**/
set firstName(value: string) {
this.#firstName = String(value);
}
setFirstName(value: string) {
this.firstName = value;
return this;
}
constructor(data: unknown = undefined) {
if (data === null || data === undefined) {
return;
}
if (typeof data === "string") {
this.applyFromObject(JSON.parse(data));
} else if (this.#isJsonAppliable(data)) {
this.applyFromObject(data);
} else {
throw new Error(
"Instance cannot be created on an unknown value, check the content being passed. got: " +
typeof data,
);
}
}
#isJsonAppliable(obj: unknown) {
const g = globalThis as unknown as { Buffer: any; Blob: any };
const isBuffer =
typeof g.Buffer !== "undefined" &&
typeof g.Buffer.isBuffer === "function" &&
g.Buffer.isBuffer(obj);
const isBlob = typeof g.Blob !== "undefined" && obj instanceof g.Blob;
return (
obj &&
typeof obj === "object" &&
!Array.isArray(obj) &&
!isBuffer &&
!(obj instanceof ArrayBuffer) &&
!isBlob
);
}
/**
* casts the fields of a javascript object into the class properties one by one
**/
applyFromObject(data = {}) {
const d = data as Partial<Mother>;
if (d.firstName !== undefined) {
this.firstName = d.firstName;
}
}
/**
* Special toJSON override, since the field are private,
* Json stringify won't see them unless we mention it explicitly.
**/
toJSON() {
return {
firstName: this.#firstName,
};
}
toString() {
return JSON.stringify(this);
}
static get Fields() {
return {
firstName: "firstName",
};
}
/**
* Creates an instance of NullableResponseActionDto.Mother, and possibleDtoObject
* needs to satisfy the type requirement fully, otherwise typescript compile would
* be complaining.
**/
static from(possibleDtoObject: NullableResponseActionDtoType.MotherType) {
return new NullableResponseActionDto.Mother(possibleDtoObject);
}
/**
* Creates an instance of NullableResponseActionDto.Mother, and partialDtoObject
* needs to satisfy the type, but partially, and rest of the content would
* be constructed according to data types and nullability.
**/
static with(
partialDtoObject: PartialDeep<NullableResponseActionDtoType.MotherType>,
) {
return new NullableResponseActionDto.Mother(partialDtoObject);
}
copyWith(
partial: PartialDeep<NullableResponseActionDtoType.MotherType>,
): InstanceType<typeof NullableResponseActionDto.Mother> {
return new NullableResponseActionDto.Mother({
...this.toJSON(),
...partial,
});
}
clone(): InstanceType<typeof NullableResponseActionDto.Mother> {
return new NullableResponseActionDto.Mother(this.toJSON());
}
};
/**
* The base class definition for father
**/
static Father = class Father {
/**
*
* @type {string}
**/
#firstName: string = "";
/**
*
* @returns {string}
**/
get firstName() {
return this.#firstName;
}
/**
*
* @type {string}
**/
set firstName(value: string) {
this.#firstName = String(value);
}
setFirstName(value: string) {
this.firstName = value;
return this;
}
constructor(data: unknown = undefined) {
if (data === null || data === undefined) {
return;
}
if (typeof data === "string") {
this.applyFromObject(JSON.parse(data));
} else if (this.#isJsonAppliable(data)) {
this.applyFromObject(data);
} else {
throw new Error(
"Instance cannot be created on an unknown value, check the content being passed. got: " +
typeof data,
);
}
}
#isJsonAppliable(obj: unknown) {
const g = globalThis as unknown as { Buffer: any; Blob: any };
const isBuffer =
typeof g.Buffer !== "undefined" &&
typeof g.Buffer.isBuffer === "function" &&
g.Buffer.isBuffer(obj);
const isBlob = typeof g.Blob !== "undefined" && obj instanceof g.Blob;
return (
obj &&
typeof obj === "object" &&
!Array.isArray(obj) &&
!isBuffer &&
!(obj instanceof ArrayBuffer) &&
!isBlob
);
}
/**
* casts the fields of a javascript object into the class properties one by one
**/
applyFromObject(data = {}) {
const d = data as Partial<Father>;
if (d.firstName !== undefined) {
this.firstName = d.firstName;
}
}
/**
* Special toJSON override, since the field are private,
* Json stringify won't see them unless we mention it explicitly.
**/
toJSON() {
return {
firstName: this.#firstName,
};
}
toString() {
return JSON.stringify(this);
}
static get Fields() {
return {
firstName: "firstName",
};
}
/**
* Creates an instance of NullableResponseActionDto.Father, and possibleDtoObject
* needs to satisfy the type requirement fully, otherwise typescript compile would
* be complaining.
**/
static from(possibleDtoObject: NullableResponseActionDtoType.FatherType) {
return new NullableResponseActionDto.Father(possibleDtoObject);
}
/**
* Creates an instance of NullableResponseActionDto.Father, and partialDtoObject
* needs to satisfy the type, but partially, and rest of the content would
* be constructed according to data types and nullability.
**/
static with(
partialDtoObject: PartialDeep<NullableResponseActionDtoType.FatherType>,
) {
return new NullableResponseActionDto.Father(partialDtoObject);
}
copyWith(
partial: PartialDeep<NullableResponseActionDtoType.FatherType>,
): InstanceType<typeof NullableResponseActionDto.Father> {
return new NullableResponseActionDto.Father({
...this.toJSON(),
...partial,
});
}
clone(): InstanceType<typeof NullableResponseActionDto.Father> {
return new NullableResponseActionDto.Father(this.toJSON());
}
};
constructor(data: unknown = undefined) {
if (data === null || data === undefined) {
this.#lateInitFields();
return;
}
if (typeof data === "string") {
this.applyFromObject(JSON.parse(data));
} else if (this.#isJsonAppliable(data)) {
this.applyFromObject(data);
} else {
throw new Error(
"Instance cannot be created on an unknown value, check the content being passed. got: " +
typeof data,
);
}
}
#isJsonAppliable(obj: unknown) {
const g = globalThis as unknown as { Buffer: any; Blob: any };
const isBuffer =
typeof g.Buffer !== "undefined" &&
typeof g.Buffer.isBuffer === "function" &&
g.Buffer.isBuffer(obj);
const isBlob = typeof g.Blob !== "undefined" && obj instanceof g.Blob;
return (
obj &&
typeof obj === "object" &&
!Array.isArray(obj) &&
!isBuffer &&
!(obj instanceof ArrayBuffer) &&
!isBlob
);
}
/**
* casts the fields of a javascript object into the class properties one by one
**/
applyFromObject(data = {}) {
const d = data as Partial<NullableResponseActionDto>;
if (d.mother !== undefined) {
this.mother = d.mother;
}
if (d.father !== undefined) {
this.father = d.father;
}
if (d.firstUncle !== undefined) {
this.firstUncle = d.firstUncle;
}
if (d.secondUncle !== undefined) {
this.secondUncle = d.secondUncle;
}
this.#lateInitFields(data);
}
/**
* These are the class instances, which need to be initialised, regardless of the constructor incoming data
**/
#lateInitFields(data = {}) {
const d = data as Partial<NullableResponseActionDto>;
if (!(d.mother instanceof NullableResponseActionDto.Mother)) {
this.mother = new NullableResponseActionDto.Mother(d.mother || {});
}
if (!(d.firstUncle instanceof UncleDto)) {
this.firstUncle = new UncleDto(d.firstUncle || {});
}
}
/**
* Special toJSON override, since the field are private,
* Json stringify won't see them unless we mention it explicitly.
**/
toJSON() {
return {
mother: this.#mother,
father: this.#father,
firstUncle: this.#firstUncle,
secondUncle: this.#secondUncle,
};
}
toString() {
return JSON.stringify(this);
}
static get Fields() {
return {
mother$: "mother",
get mother() {
return withPrefix("mother", NullableResponseActionDto.Mother.Fields);
},
father$: "father",
get father() {
return withPrefix("father", NullableResponseActionDto.Father.Fields);
},
firstUncle$: "firstUncle",
get firstUncle() {
return withPrefix("firstUncle", UncleDto.Fields);
},
secondUncle: "secondUncle",
};
}
/**
* Creates an instance of NullableResponseActionDto, and possibleDtoObject
* needs to satisfy the type requirement fully, otherwise typescript compile would
* be complaining.
**/
static from(possibleDtoObject: NullableResponseActionDtoType) {
return new NullableResponseActionDto(possibleDtoObject);
}
/**
* Creates an instance of NullableResponseActionDto, and partialDtoObject
* needs to satisfy the type, but partially, and rest of the content would
* be constructed according to data types and nullability.
**/
static with(partialDtoObject: PartialDeep<NullableResponseActionDtoType>) {
return new NullableResponseActionDto(partialDtoObject);
}
copyWith(
partial: PartialDeep<NullableResponseActionDtoType>,
): InstanceType<typeof NullableResponseActionDto> {
return new NullableResponseActionDto({ ...this.toJSON(), ...partial });
}
clone(): InstanceType<typeof NullableResponseActionDto> {
return new NullableResponseActionDto(this.toJSON());
}
}
export abstract class NullableResponseActionDtoFactory {
abstract create(data: unknown): NullableResponseActionDto;
}
type PartialDeep<T> = {
[P in keyof T]?: T[P] extends Array<infer U>
? Array<PartialDeep<U>>
: T[P] extends object
? PartialDeep<T[P]>
: T[P];
};
/**
* The base type definition for nullableResponseActionDto
**/
export type NullableResponseActionDtoType = {
/**
* Mother info should be present
* @type {NullableResponseActionDtoType.MotherType}
**/
mother: NullableResponseActionDtoType.MotherType;
/**
* Father name is not essential for some goverment papers.
* @type {NullableResponseActionDtoType.FatherType}
**/
father?: NullableResponseActionDtoType.FatherType;
/**
* Uncle is a separate dto, therefor we use that entity
* @type {UncleDto}
**/
firstUncle: UncleDto;
/**
* Second uncle is optional
* @type {UncleDto}
**/
secondUncle?: UncleDto;
};
// eslint-disable-next-line @typescript-eslint/no-namespace
export namespace NullableResponseActionDtoType {
/**
* The base type definition for motherType
**/
export type MotherType = {
/**
*
* @type {string}
**/
firstName: string;
};
// eslint-disable-next-line @typescript-eslint/no-namespace
export namespace MotherType {}
/**
* The base type definition for fatherType
**/
export type FatherType = {
/**
*
* @type {string}
**/
firstName: string;
};
// eslint-disable-next-line @typescript-eslint/no-namespace
export namespace FatherType {}
}