[prefer-readonly-type] Rework this rule.
See original GitHub issueFunction Return Types
The return type of functions shouldn’t be enforced to be immutable (by default) (this behavior can currently be turned on with the allowMutableReturnType
option).
Following from this, the rule @typescript-eslint/explicit-function-return-type
should no longer be a recommend external rule.
Enforce Mutable Return Types
If the return type has to immutable then something very non-functional is going on. What happens to the data after it is returned by a function should be of no concern to the function itself. Mutable return types are more compatible with 3rd-party non-function code as readonly types can not be given as mutable types in TypeScript (while mutable types can be given as either a mutable or readonly type).
An option to enforce this behaviour should be added to the rule (whether this is the default behavior or not is currently undecided).
Type Aliases
Often a mutable type needs to be aliased. This rule should not trigger an error when a mutable type is aliased (by default), only when the mutable type is used.
Care will be need to be taken when implementing this to keep performance good - we don’t want to reevaluate every instance of type alias usage to check whether it’s mutable or not.
New Rule
As this is such a large change to the current implementation of rule, it’s probably best to instead create this change as a new rule and deprecate the current rule. Any suggestions on a new rule name?
Issue Analytics
- State:
- Created 3 years ago
- Comments:18
Top GitHub Comments
I think I understand better what the proposal is now. So instead of explicitly requiring types/interfaces to be declared with
readonly
attributes, the@typescript-eslint/prefer-readonly-parameter-types
rule would implicitly enforce this requirement by not allowing you to pass anything that is not declared deeply readonly into any of your functions?I’m hesitant to remove/deprecate the rules that requires explicit
readonly
attributes orReadonlyArray
types in case of array etc. These were the first rules added totslint-immutable
and I know they were was appreciated by many users. I think it serves a purpose to train/encourage junior developers to make things immutable at the time they write code that declare the types rather than later when they use the type. It also provides a quick-fix to add thereadonly
attribute that I use daily when I declare types (since I am lazy and don’t want to type it out myself 😃). There are also cases where you would declare types but not pass them into functions but they are of course rare, eg. when declaring a globalconst
and referencing it directly in a function. As you mentioned the idea of the rule was to make everything immutable, except types/fields explicitly marked mutable. Kind of how it works in some functional-first languages like ocaml/reasonml. Typescript does not have amutable
attribute but to mark types/fields mutable you would name them in a pattern that is ignored by theprefer-readonly-type
rule.So from the above I think you can have two different approaches to immutability.
The first approach would be to explicitly require declaration of readonly types everywhere and when you need mutable types (eg when using 3rd party functions) you need to cast them to non-readonly types (which admittedly is ugly) or mark them as mutable by naming convention.
The second approach would be to only require readonly types to be passed into your own functions which could avoid some pain when calling 3rd party functions.
I think we should support both these approaches. By enabling both
prefer-readonly-type
and@typescript-eslint/prefer-readonly-parameter-types
you can use the first approach, and by only enabling@typescript-eslint/prefer-readonly-parameter-types
you could use the second approach.However I can see how the rules
immutable-data
,prefer-readonly-type
, and@typescript-eslint/prefer-readonly-parameter-types
overlap in some regards and requires/checks the same things but in different ways, which adds overhead to the linting and I think this is what you are trying to solve by deprecatingprefer-readonly-type
? I think this is something we could investigate further to improve somehow.Please let me know if I misunderstood anything 😃.
@jonaskello I’ve been thinking that it might be best to rename the rule to
prefer-readonly-type-declarations
and keep the originalprefer-readonly-type
rule around but deprecated. My reasoning being that there are a few breaking changes between the new and old rules. Do you think this would be the way to go about things?