My dilemma involves an unchangeable class Settings
with a multitude of attributes, and my goal is to find a simple method to create a modified version. Initially, I approached this challenge by implementing the following code:
class Settings {
private constructor(public readonly a: number,
public readonly b: number) {
}
static newSettings() {
return new Settings(1, 2);
}
withA(a: number) {
return new Settings(a, this.b);
}
withB(a: number) {
return new Settings(this.a, b);
}
}
This approach mirrors how I handle such tasks in Java (with assistance from Lombok for generating boilerplate). However, as my project grew, I realized that this method was not scalable. Subsequently, I transitioned to a different strategy:
interface ISettings {
readonly a?: number
readonly b?: number
}
class Settings implements ISettings {
readonly a: number = 1
readonly b: number = 2
private constructor(base?: ISettings, overrides?: ISettings) {
for (const k of Object.keys(this)) {
// @ts-ignore
this[k] = overrides?.[k] ?? base?.[k] ?? this[k]; // <---- PROBLEM
}
}
static newSettings() {
return new Settings();
}
with(overrides: ISettings) {
return new Settings(this, overrides);
}
}
This revised implementation works effectively, although it necessitated the use of @ts-ignore
for one line, which, in my opinion, should ideally function smoothly without any need for additional intervention.
While options like immerjs
offer enhanced functionality, my main concern remains focused on achieving correct typings. How can I ensure that the typifications are accurate?