Home > database >  Declaring a class in TypeScript with all the properties of an existing object type
Declaring a class in TypeScript with all the properties of an existing object type

Time:12-15

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

Playground

@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);
    }
}
  • Related