The idea is to validate ngOnChanges Angular method.
- It should have
changesof typeSimpleChangesas an argument - Inside the function when accessing the property
currentChangesshould be optionally chained
So an example of invalid code is:
public ngOnChanges(notChangesName: NotSimpleShanges) {
notChangesName.property.currentValue;
}
And an example of valid code is:
public ngOnChanges(changes: SimpleShanges) {
changes.property?.currentValue;
}
The best I came with is
"no-restricted-syntax": [
"error",
{
"message": "Changes currentValue should be optionally chained",
"selector": "MemberExpression[optional=false] > Identifier[name=\"currentValue\"]"
},
{
"message": "ngOnChanges should have 'changes' as an argument of type 'SimpleChanges'",
"selector": "MethodDefinition[key.name=\"ngOnChanges\"] > FunctionExpression > Identifier[name!=\"changes\"]"
},
{
"message": "ngOnChanges should have 'changes' as an argument of type 'SimpleChanges'",
"selector": "MethodDefinition[key.name=\"ngOnChanges\"] > FunctionExpression > BlockStatement:not(:has(Parameter))"
}
]
The problems are:
Selector
MemberExpression[optional=false] > Identifier[name=\"currentValue\"]checkscurrentValueis optionally chained to any variable. I need it to be checked if the parent has namechanges(changes.field.currentValue)Type of
changesis not checked by selectorMethodDefinition[key.name=\"ngOnChanges\"] > FunctionExpression > Identifier[name!=\"changes\"]. It should be of typeSimpleChanges
UPD: Current solution is:
"no-restricted-syntax": [
"error",
{
"message": "Properties 'currentValue | firstChange | previousValue | isFirstChange' should be optional",
"selector": "MethodDefinition[key.name='ngOnChanges'] MemberExpression[object.object.name='changes'][optional=false][property.name=/.*/]"
},
{
"message": "ngOnChanges should have 'changes' as an argument",
"selector": "MethodDefinition[key.name='ngOnChanges'] > FunctionExpression > Identifier[name!='changes']"
},
{
"message": "ngOnChanges should have 'changes: NgChanges' as an argument",
"selector": "MethodDefinition[key.name='ngOnChanges'] > FunctionExpression > Identifier > TSTypeAnnotation > TSTypeReference > Identifier[name!='SimpleChanges']"
},
{
"message": "ngOnChanges should have one argument 'changes: NgChanges'",
"selector": "MethodDefinition[key.name='ngOnChanges'] > FunctionExpression[params.length!=1]"
}
]