Search code examples
typescriptinheritanceinterface

Typescript Inheritance in Interfaces


First time using typescript, and would like to know how to best deal with this situation.

I have some json data coming from API, say

{"name" : "A Person", "age": "25", createdAt: "timestamp"}

And I have an interface IPersonData which represents the incoming JSON.

export interface IPersonData {
  name: string;
  createdAt: string;
  age: string;
}

But then an actual Person Object within in the system:

export interface IPerson extends IPersonData {
  createdAt: DateTime; //this is the luxon DateTime
  age: number;
}

Webstorm does not yell at me (and actually provides an icon saying its overridden) but the compiler hates it, letting me know Type 'DateTime' is not assignable to type 'string'.

I have tried this too,

 export interface IPerson extends Omit<IPersonData, "createdAt">{
  createdAt: DateTime; //this is the luxon DateTime
  age: number;
}

Can I override in typescript, and if not, is there value in representing the JSON coming into the system, (We use the same types to validate the JSON leaving the API).


Solution

  • You're almost there with your final snippet. You probably got this error:

    Interface 'IPerson' incorrectly extends interface 'Omit<IPersonData, "createdAt">'.
      Types of property 'age' are incompatible.
        Type 'number' is not assignable to type 'string'.(2430)
    

    What is important to note is that it's not complaining about createdAt. So its working for that field. And since you are changing age to a number from a string, you need to omit that one too.

    One thing you may not know, is that you can omit many fields with Omit by passing in a union of strings.

    export interface IPerson extends Omit<IPersonData, 'createdAt' | 'age'> {
      createdAt: DateTime;
      age: number;
    }
    

    Which does what you expect.

    Playground