38
interface BaseInter {
  name: string;
  test(): void;
}
    
abstract class Abs implements BaseInter { }

In TypeScript, compiler complaints that the class incorrectly implements the interface:

name is missing in type Abs.

Here Abs is an abstract class and so why do we need to implement the interface over there?

Tortila
  • 158
  • 8
Jerin Joseph
  • 759
  • 1
  • 7
  • 22

4 Answers4

63

You need to re-write all of the members/methods in the interface and add the abstract keyword to them, so in your case:

interface baseInter {
    name: string;
    test();
}

abstract class abs implements baseInter {
    abstract name: string;
    abstract test();
}

(code in playground)

There was a suggestion for it: Missing property declaration in abstract class implementing interfaces but it was declined for this reason:

Although, the convenience of not writing the declaration would be nice, the possible confusion/complexity arising from this change would not warrant it. by examine the declaration, it is not clear which members appear on the type, is it all properties, methods, or properties with call signatures; would they be considered abstract? optional?

Nitzan Tomer
  • 155,636
  • 47
  • 315
  • 299
13

You can get what you want with a slight trick that defeats the compile-time errors:

interface baseInter {
    name : string;
    test();
}

interface abs extends baseInter {}

abstract class abs implements baseInter{
}

This trick takes advantage of Typescript's Declaration Merging, and was originally presented here and posted on a related SO question here.

Design.Garden
  • 3,607
  • 25
  • 21
  • Be careful though. There is no error if properties or methods are not implemented in the inherited class. So even an empty inherited class would be valid in this case. – Tortila Mar 15 '23 at 19:00
  • But it works as intended when baseInter is an abstract class. – Tortila Mar 15 '23 at 19:28
0

Interfaces are used for defining a contract regarding the shape of an object.

Use constructor to pass in properties to the class

interface BaseInter {
  name : string;
  test(): boolean;
}

abstract class Abs implements BaseInter {
  constructor(public name: string) {}
  test(): boolean {
    throw new Error('Not implemented')
  }
}
Andrii Abramov
  • 10,019
  • 9
  • 74
  • 96
Shlomi Lachmish
  • 541
  • 5
  • 14
0

If Base is an interface (as in this answer), there is no error in Derived. But if Base is an abstract class, it works as intended.

abstract class Base {
  abstract name: string;
  abstract test(): void;
}

interface Abstract extends Base { }
abstract class Abstract { }

class Derived extends Abstract {
  // ERROR: Non-abstract class 'Derived' does not implement inherited abstract member 'name' from class 'Abstract'.
  // ERROR: Non-abstract class 'Derived' does not implement inherited abstract member 'test' from class 'Abstract'.
}

It feels hacky for me, but as for Typescript 4.9.5 it works.

Tortila
  • 158
  • 8