Scipion Scipion - 1 month ago 20
TypeScript Question

Create a set of common class properties in TS

I am very new in typescript.

I have the following code :

export interface MetaObject {
public creationDate: string,
public modificationDate: string
}

export class A implements MetaObject {
constructor(
public id:number,
) { }
}

export class B implements MetaObject {
constructor(
public id:number,
) { }
}


That big of code triggers that error :

TS2420 Class 'Booking' incorrectly implements interface 'MetaObject'.
Property 'active' is missing in type 'Booking'.


I am trying to have a MetaObject which some properties I don't want to specify in my constructor, but that I want to exist on all my objects. So far I have created an interface with these properties and my classes are implementing it. Is that the right way to do so ? The purpose here is really not to have to add anything else in the classes, but keep the common properties names, types, ... in the interface.

Is that the right way to do so ?

Answer

No, that's not the way to do it, a few things:

(1) Everything you put in an interface is public, there's no need to specify that the properties are public, and it results in an error.

(2) If you implement an interface you must then add those properties to your class, otherwise the compiler will complain about:

Class 'A' incorrectly implements interface 'MetaObject'.
Property 'creationDate' is missing in type 'A'.

So it should look like:

interface MetaObject {
    creationDate: string;
    modificationDate: string;
}

class A implements MetaObject {
    constructor(
        public id: number,
        public creationDate: string,
        public modificationDate: string) { }
}

class B implements MetaObject {
    constructor(
        public id: number,
        public creationDate: string,
        public modificationDate: string) { }
}

(code in playground)

If you don't want to re-write implementation then you need a base class:

abstract class MetaObject {
     constructor(
        protected creationDate: string,
        protected modificationDate: string) { }

     getCreationDate() {
         return this.creationDate;
     }

     getModificationDate() {
         return this.modificationDate;
    }
}

class A extends MetaObject {
    constructor(public id: number, creationDate: string, modificationDate: string) {
        super(creationDate, modificationDate);
    }
}

class B extends MetaObject {
    constructor(public id: number, creationDate: string, modificationDate: string) {
        super(creationDate, modificationDate);
    }
}

(code in playground)

Another option is to use mixins, but I think that it's an overkill in your situation.

Comments