2

The following code is taken from angular source code, di.ts.

export interface AttributeDecorator { 
  (name: string): any;
  new (name: string): Attribute;
}

I understand this is an interface. But what new (name: string): Attribute is doing and why there is two types for name, string and any.

The above code is followed by

export interface Attribute { attributeName?: string; }
export const Attribute: AttributeDecorator = makeParamDecorator('Attribute', (attributeName?: string) => ({attributeName}));
Vishnu Sureshkumar
  • 2,246
  • 6
  • 35
  • 52

1 Answers1

2

(name: string): any indicates that a function that implements this interface is supposed to be called as regular function; it's called with name string argument and returns any.

new (name: string): Attribute indicates that a function that implements this interface is supposed to be used as a constructor, be called with new and return Attribute object.

This decorator interface describes the fact that Angular decorator function can be used as both @Attribute(...) parameter decorator function and new Attribute(...) constructor, and they behave differently when being called like that.

new Attribute(...) can be used for annotations in ES5 and ES6, as shown in this answer.

The function that is described by this interface and created by makeParamDecorator factory is supposed to work roughly like:

// decorator factory
const MyAttributeDecorator = function (attributeName?: string) {
  if (new.target)
    // Attribute object
    return { attributeName };
  else
    // parameter decorator
    return (target, prop, paramIndex) => { ... };
}
Estus Flask
  • 206,104
  • 70
  • 425
  • 565
  • How it handle if they are using any instead of Attribute? like `new (name: string): any;` – Ramesh Rajendran Dec 18 '17 at 11:18
  • @RameshRajendran `@Attribute` is [parameter decorator](https://www.typescriptlang.org/docs/handbook/decorators.html#parameter-decorators), it's used as `constructor(@Attribute(...) foo)`. I guess `any` refers to this statement, *The return value of the parameter decorator is ignored*. When being called with `new`, the decorator returns an instance of Attribute, as the interface says. – Estus Flask Dec 18 '17 at 11:23