question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[prefer-readonly-type] Rework this rule.

See original GitHub issue

Function 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:open
  • Created 3 years ago
  • Comments:18

github_iconTop GitHub Comments

1reaction
jonaskellocommented, Aug 2, 2021

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 or ReadonlyArray types in case of array etc. These were the first rules added to tslint-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 the readonly 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 global const 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 a mutable attribute but to mark types/fields mutable you would name them in a pattern that is ignored by the prefer-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 deprecating prefer-readonly-type? I think this is something we could investigate further to improve somehow.

Please let me know if I misunderstood anything 😃.

0reactions
RebeccaStevenscommented, Aug 9, 2021

@jonaskello I’ve been thinking that it might be best to rename the rule to prefer-readonly-type-declarations and keep the original prefer-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?

Read more comments on GitHub >

github_iconTop Results From Across the Web

eslint-plugin-functional/prefer-readonly-type.md at main - GitHub
Prefer readonly types over mutable types (prefer-readonly-type) This rule enforces use of the readonly modifier and readonly types.
Read more >
prefer-readonly - TypeScript ESLint
This rule requires type information to run. Member variables with the privacy private are never permitted to be modified outside of their declaring...
Read more >
Configuration | ts-belt - GitHub Pages
TS Belt returns immutable data, so enabling the functional/prefer-readonly-type rule is recommended.
Read more >
Default rule reference - Azure DevOps - Microsoft Learn
There are two main types of rules, auto-generated rules and custom ... field as read-only not only applies the rule on the work...
Read more >
Considerations for Field Update Actions - Salesforce Help
Therefore, a workflow rule can update fields even though they are hidden on the user's page layout. ... Read-only fields like formula or...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found