A common structure I use in TS is taking a plain JSON object definition and turning it into a class at runtime. For example:
export type LessonDef = {
id: string
title: string
slug: string
shortdesc: string
explanation: string
exercises: {
from: string
message: string
translation: string
hint?: string
feedback?: { [key: string]: string }
}[]
}
export class Lesson {
constructor(readonly def: LessonDef) {
Object.assign(this, def)
}
// Additional methods go here
}
The problem is that the type system doesn't understand the result of the Object.assign
. How can I tell TypeScript that Lesson
extends the type of LessonDef
?
CodePudding user response:
Please see related answer
You can merge your class declaration and interface.
Consider this example:
interface Lesson {
id: string
title: string
slug: string
shortdesc: string
explanation: string
exercises: {
from: string
message: string
translation: string
hint?: string
feedback?: { [key: string]: string }
}[]
}
declare let x: Lesson;
class Lesson {
constructor(def: Lesson) {
Object.assign(this, def);
}
}
const result = new Lesson(x)
result.exercises // ok
@Cerberus thank you for pointing out my mistake regarding using {... def}
instead of def
However, there is a drawback, you can refer to this.exercises
before Object.assign
class Lesson {
constructor(def: Lesson) {
this.exercises //ok, <----- DRAWBACK!
Object.assign(this, def);
}
}