Joe Lapp
Joe Lapp

Reputation: 2975

Extend a Typescript class from an interface

How do I extend a class with the properties of an interface in Typescript? I realize that this would necessarily leave the properties uninitialized.

My sole purpose is to reduce code redundancy. The property declarations that appear in the interface would identically appear in each class implementation. I'd rather maintain those properties centrally from just the interface.

I would like to write something like the following, but this is riddle with errors:

interface Spec {
    id: number;
}

class Model<S> {
    [K extends keyof S: string]: S[K];
}

class MyModel extends Model<Spec> {
    // id: number -- implicit
}

Instead, I find myself able to write this, which builds but doesn't do the job:

interface Spec {
    id: number;
}

class Model<S, K extends keyof S> {
    [K: string]: S[K];
}

class MyModel extends Model<Spec, keyof Spec> {
    // id: number -- implicit
}

It's clear that it doesn't do the job when I add implements Spec to MyModel:

class MyModel extends Model<Spec, keyof Spec> implements Spec {
    // id: number -- implicit
}

Because then I get the error, Property 'id' is missing in type 'MyModel'.

I'm not worried about leaving the interface properties uninitialized, because that can always be done from the constructor. The plethora of interfaces I'm dealing with is the greater nightmare.

NOTE: I'm using an underlying JS module to populate the spec properties, so the compiler won't necessarily complain if their declarations aren't provided.

Upvotes: 1

Views: 1372

Answers (1)

Ryan Cavanaugh
Ryan Cavanaugh

Reputation: 221362

You can do this to declare that a class has all the members of an interface:

class MyModel {
  // usual stuff
}
interface MyModel extends Spec { /* don't need to write anything here */ }

This feature is called declaration merging.

Upvotes: 3

Related Questions