Why does TypeScript duplicate a component during implementation?

Why can TypeScript duplicate a component in implements ?

 import { Component,OnInit } from '@angular/core'; export class CreateVersionComponent implements OnInit, OnInit, OnInit { }// no error export class CreateVersionComponent extends OnInit, OnInit, OnInit { }// getting error 

But it throws a repeating identifier error while the component expands.

So what is the reason for TypeScript adopting the duplicate component during implementation? What situation do we need to use?

+5
source share
4 answers

To understand why the first code is not a problem, but secondly, you need to understand the difference between a class and an interface. An interface is a guarantee that its developer will at least provide members of the interface. It does not provide any real functionality. However, the class may contain an implementation code; you can inherit from a class to reuse this code and change its behavior by adding new code or changing existing implementations.

This means that implements and extends have different meanings. implements says: I can guarantee every consumer of this class that he will have at least interface members. Since there is no real implementation in the interface, there is no problem to make several of these guarantees if the class implements all of them. You are right that it does not make sense to add the same guarantee several times, but it is also very painful. TypeScript creators might have forbidden the implementation of an interface several times. We can guess why they did not; I assume that since TypeScript is based on JavaScript and JS is quite forgiving, they did not want to ban anything that does no harm. Note that TS is a type layer on top of JS, and all type information will eventually be deleted at compile time in JS. In this context, dropping multiple repetitive implementations of the interface will not really hurt, as the result will be exactly the same.

Besides implements , extends is another story. Although there are several languages โ€‹โ€‹that allow multiple inheritance (for example, C ++), multiple inheritance is associated with many difficult implementation details (for example, a diamond problem or calling base class constructors), so many languages โ€‹โ€‹do not support it with the idea that it causes more problems than can decide. TypeScript does not allow multiple inheritance, which means that you cannot use extends with more than one base class in general. Unlike interface implementations, class inheritance has implications for how the program works, and the compiler will do much more than just strip type information. Therefore, it makes sense to make a mistake there.

+7
source

Existing answers explain well:

  • Class versus interface.
  • multiple inheritance and implementation of several interfaces.
  • Interfaces erased by compilation mean that the compiled code is no different from redundant interfaces in the implements clause.

But some confusion remains. To approach the question from a different angle:

What situation do we need to use?

No. There is no situation where you need to declare redundant interfaces. It reminds me of something like this:

var v = v = v = 66

Yes, that's fine as far as the compiler goes. No, you never need to do this.

Why is this accepted?

It's easy to see why someone (especially someone with a Java background) might be confused by the lack of a warning. After all, Eclipse has been warning me of this for many years (Hello, Serializable !).

Having the same interface named several times in the same class definition is a bit strange. This may help consider an example of a redundant interface that is likely to happen:

 interface StringProducer { getString: () => string; } class Parent implements StringProducer { getString = function(): string { return 'x'; } } class Child extends Parent implements StringProducer { getString = function() : string { return 'y'; } } class GrandChild extends Child implements StringProducer { getString = function(): string { return 'z'; } } console.log(new Parent().getString()); console.log(new Child().getString()); console.log(new GrandChild().getString()); 

You can (freely) think of the GrandChild class as follows:

public class GrandChild implements StringProducer, StringProducer, StringProducer {

since the class implements all its interfaces and their ancestors.

Should the compiler (or linter, perhaps) bark about this? Do I have to force remove the implements clause with Child and GrandChild ?

I think this is largely a matter of preference. For example, when I open GrandChild in my IDE, I can see in this file all the interfaces that the class implements. On the other hand, I might feel that this is just noise, and you want a warning.

The compiler, of course, doesnโ€™t care and doesnโ€™t need to. But I can understand why you might need a warning for this. The question at the end of the day seems to me (to me): "Why is there no tslint rule for redundant interfaces?" This is a reasonable question that I cannot answer. You can always write such a rule and share it with the rest of us.

+3
source

TypeScript does not allow multiple inheritance like Java, C #, etc. Thus, the second example will not work in the first place, because TSC thinks that you are trying to extend several classes before it fails, because it is the same class.

In the first case, I agree that he has to say something, because this is probably a small mistake. On the other hand, this is not semantically incorrect. When you implement methods in the first OnInit , you implement it for both the second and the third, so you should be covered.

+1
source

The answer is very simple.

Typescript does not allow multiple inheritance .

This means that one class cannot inherit from multiple classes. (This is for 'extends').

Now let's move on to "implements . "

In this case, we are talking about interfaces . You can implement as many interfaces that you need.

Keep in mind that implementing interfaces does not mean inheritance. It just means that you are executing various Models in your class, to which your class definition must correspond.

Therefore, an extension error (due to multiple inheritance that is not allowed) No implementation errors (due to multiple interface implementation that is allowed)

+1
source

Source: https://habr.com/ru/post/1273398/


All Articles