45

I'm trying to set an input alias in a directive following this example

  @Input('appAvatarColor') name: string;

The program is working, but I'm receiving this warning from TS Lint

the directive input property should not be renamed

The directive selector is this

@Directive({
  selector: '[appAvatarColor]'
})

Am I doing something wrong?
Why is this considered a bad practice by default?

3
  • 2
    I suspect you have "no-input-rename": true rule in your tslint.json file Commented May 17, 2017 at 19:58
  • 8
    @yurzui yes. That's correct. I'm using the standard tslint.json generated by angular cli. My question is why is this considered a bad practice by default? Commented May 17, 2017 at 20:13
  • The accepted answer is now deprecated as we have eslint with Angular. I have added a new answer for eslint Commented Sep 27, 2022 at 9:03

5 Answers 5

60

You can either turn off rule in tslint.json

"no-input-rename": false

or disable checking for only specific line like:

// tslint:disable-next-line:no-input-rename
@Input('appAvatarColor') name: string;

My question is why is this considered a bad practice by default?

  • Two names for the same property (one private, one public) is inherently confusing.

  • You should use an alias when the directive name is also an input property, and the directive name doesn't describe the property.

From https://angular.io/docs/ts/latest/guide/style-guide.html#!#05-13

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

4 Comments

for the "-input-rename, I can agree that renames are confusing, after all the type of the field remains the same externally/internally. But for @Output there is also a no-output-rename: true by default. And I find this logic harder to comprehend, because unlike inputs, it's not symetrical. e.g. Externally it looks like an event:(rowDeleted)="onRowDelete($event)", but internally it's not an event, but an EventEmitter. Naming it rowDeleted would make it look like a boolean. It make more sense to define it as @Output('rowDeleted') private rowDeletedEventEmitter;, right?
Nevertheless, this is a great answer :). But curious about your opinion regarding the no-output-rename as well.
For eslint v8.2.0 write "no-input-rename": 0 Or you'll get Error: .eslintrc.json#overrides[0]:
Point 1: aliasing is typically done to solve inherently confusing binding names isnt it? Especially when forced to use a name eg.@Input('cdkListItemTemplate') item: TemplateRef<any>;
33

You can implement it the following way :

@Input() appAvatarColor: string;

1 Comment

I believe you are not adding a alias here, you are only declaring your variable as 'appAvatarColor' instead of 'name'
5

You should rename @Input('appAvatarColor') name: string; to something else for this to differ from the directive name. You can do @Input('avatarColor') name: string; and then simplify it by @Input() avatarColor: string;

Comments

4

With new Angular version, tslint is gone and we need to use eslint. For Eslint, you need to modify rules inside the .eslintrc.json file and add "@angular-eslint/no-input-rename" as below.

Example:

"rules": {
        // ..... some rules
        "@angular-eslint/no-input-rename": [
          "warn",
          { 
            "allowedNames": ["name"]
          }
        ],
       //.... more rules
     }

1 Comment

Thank you @Shashank! Also "@angular-eslint/no-output-rename": "warn"
1

The right way to do it should be the following:

@Input() appAvatarColor: string;

Comments

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.