12

Given is the following Angular component:

export class NumberComponent implements NumberInterface {
  @Input() number;
  constructor() { }
}

Now I'm looking forward to implement the NumberInterface. That's what I've got so far:

export interface NumberInterface {
  number: number
}

Basically, I'm using the type Function to define the Decorator. Now I'm wondering if there is a more specific way to do this. The interface should force the component to implement angular's @Input decorator.

1
  • 1
    NumberComponent implements NumberInterface isn't a thing in Angular. Despite the name, it's not a class interface, but simply a collection of types. Commented Apr 20, 2018 at 19:39

1 Answer 1

26

Interfaces in Typescript strictly do not have value, as they are entities that only exist for type-checking and are not compiled into JS.

You can't define a decorator in an interface because the decorator has value. It's a function that takes an argument and gives value to the class property, and not a type.

Angular's @Input decorators themselves do have a typing, but it's impossible to type them in a lower-order class since that property is itself already a type, but given value by the decorator:

export interface ITest {

  prop: Input;
  prop2: InputDecorator;

}

export class Test implements ITest {

  @Input('thing') prop: string;
  @Input('thing2') prop2: string;

}

// typeerror: Test does not correctly implement ITest

However, component classes can be derived from in Angular, and the parent class' decorators will be inherited by the child. This is useful if you want to implement strong typing alongside a more polymorphic approach to your code:

export class NumberBase {

  @Input('number') number: number;

}

export class NumberComponent extends NumberBase {


  ngOnInit() {
    console.log(this.number); // works!
  }

}

Components can extend either plain TS classes or fully decorated Angular components.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks, extending brings exactly the behavior I want. Such a brilliant answer!
I believe super() needs to be called in the component's constructor() then since it's extending a class
yup, if you have a constructor, the super call needs to be the first line of the constructor body. The TS compiler will let you know that pretty quickly :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.