A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://typescript-eslint.io/rules/prefer-readonly-parameter-types/ below:

prefer-readonly-parameter-types | typescript-eslint

prefer-readonly-parameter-types

Require function parameters to be typed as readonly to prevent accidental mutation of inputs.

💭

This rule requires type information to run, which comes with performance tradeoffs.

Mutating function arguments can lead to confusing, hard to debug behavior. Whilst it's easy to implicitly remember to not modify function arguments, explicitly typing arguments as readonly provides clear contract to consumers. This contract makes it easier for a consumer to reason about if a function has side-effects.

This rule allows you to enforce that function parameters resolve to readonly types. A type is considered readonly if:

eslint.config.mjs

export default tseslint.config({
rules: {
"@typescript-eslint/prefer-readonly-parameter-types": "error"
}
});

.eslintrc.cjs

module.exports = {
"rules": {
"@typescript-eslint/prefer-readonly-parameter-types": "error"
}
};

Try this rule in the playground ↗

Examples
function array1(arg: string[]) {} 
function array2(arg: readonly string[][]) {}
function array3(arg: [string, number]) {}
function array4(arg: readonly [string[], number]) {}


function object1(arg: { prop: string }) {}
function object2(arg: { readonly prop: string; prop2: string }) {}
function object3(arg: { readonly prop: { prop2: string } }) {}


interface CustomArrayType extends ReadonlyArray<string> {
prop: string;
}
function custom1(arg: CustomArrayType) {}

interface CustomFunction {
(): void;
prop: string;
}
function custom2(arg: CustomFunction) {}

function union(arg: string[] | ReadonlyArray<number[]>) {}


interface Foo {
(arg: string[]): void;
}
interface Foo {
new (arg: string[]): void;
}
const x = { foo(arg: string[]): void {} };
function foo(arg: string[]);
type Foo = (arg: string[]) => void;
interface Foo {
foo(arg: string[]): void;
}
Open in Playground
function array1(arg: readonly string[]) {}
function array2(arg: readonly (readonly string[])[]) {}
function array3(arg: readonly [string, number]) {}
function array4(arg: readonly [readonly string[], number]) {}


function object1(arg: { readonly prop: string }) {}
function object2(arg: { readonly prop: string; readonly prop2: string }) {}
function object3(arg: { readonly prop: { readonly prop2: string } }) {}


interface CustomArrayType extends ReadonlyArray<string> {
readonly prop: string;
}
function custom1(arg: Readonly<CustomArrayType>) {}


interface CustomFunction {
(): void;
readonly prop: string;
}
function custom2(arg: CustomFunction) {}

function union(arg: readonly string[] | ReadonlyArray<number>) {}

function primitive1(arg: string) {}
function primitive2(arg: number) {}
function primitive3(arg: boolean) {}
function primitive4(arg: unknown) {}
function primitive5(arg: null) {}
function primitive6(arg: undefined) {}
function primitive7(arg: any) {}
function primitive8(arg: never) {}
function primitive9(arg: string | number | undefined) {}

function fnSig(arg: () => void) {}

enum Foo {
a,
b,
}
function enumArg(arg: Foo) {}

function symb1(arg: symbol) {}
const customSymbol = Symbol('a');
function symb2(arg: typeof customSymbol) {}


interface Foo {
(arg: readonly string[]): void;
}
interface Foo {
new (arg: readonly string[]): void;
}
const x = { foo(arg: readonly string[]): void {} };
function foo(arg: readonly string[]);
type Foo = (arg: readonly string[]) => void;
interface Foo {
foo(arg: readonly string[]): void;
}
Open in Playground Options

This rule accepts the following options:

type Options = [
{

allow?: (
| {
from: 'file';
name: string | string[];
path?: string;
}
| {
from: 'lib';
name: string | string[];
}
| {
from: 'package';
name: string | string[];
package: string;
}
| string
)[];

checkParameterProperties?: boolean;

ignoreInferredTypes?: boolean;

treatMethodsAsReadonly?: boolean;
},
];

const defaultOptions: Options = [
{
allow: [],
checkParameterProperties: true,
ignoreInferredTypes: false,
treatMethodsAsReadonly: false,
},
];
allow

An array of type specifiers to ignore. Default: [].

Some complex types cannot easily be made readonly, for example the HTMLElement type or the JQueryStatic type from @types/jquery. This option allows you to globally disable reporting of such types.

This option takes the shared TypeOrValueSpecifier format.

Examples of code for this rule with:

{
"allow": [
{ "from": "file", "name": "Foo" },
{ "from": "lib", "name": "HTMLElement" },
{ "from": "package", "name": "Bar", "package": "bar-lib" }
]
}
interface ThisIsMutable {
prop: string;
}

interface Wrapper {
sub: ThisIsMutable;
}

interface WrapperWithOther {
readonly sub: Foo;
otherProp: string;
}


function fn1(arg: ThisIsMutable) {}


function fn2(arg: Wrapper) {}


function fn3(arg: WrapperWithOther) {}
Open in Playground
import { Foo } from 'some-lib';
import { Bar } from 'incorrect-lib';

interface HTMLElement {
prop: string;
}


function fn1(arg: Foo) {}


function fn2(arg: HTMLElement) {}


function fn3(arg: Bar) {}
Open in Playground
interface Foo {
prop: string;
}

interface Wrapper {
readonly sub: Foo;
readonly otherProp: string;
}


function fn1(arg: Foo) {}


function fn2(arg: Wrapper) {}
Open in Playground
import { Bar } from 'bar-lib';

interface Foo {
prop: string;
}


function fn1(arg: Foo) {}


function fn2(arg: HTMLElement) {}


function fn3(arg: Bar) {}
Open in Playground checkParameterProperties

Whether to check class parameter properties. Default: true.

Because parameter properties create properties on the class, it may be undesirable to force them to be readonly.

Examples of code for this rule with {checkParameterProperties: true}:

Examples of correct code for this rule with {checkParameterProperties: false}:

class Foo {
constructor(
private paramProp1: string[],
private paramProp2: readonly string[],
) {}
}
Open in Playground ignoreInferredTypes

Whether to ignore parameters which don't explicitly specify a type. Default: false.

This may be desirable in cases where an external dependency specifies a callback with mutable parameters, and manually annotating the callback's parameters is undesirable.

Examples of code for this rule with {ignoreInferredTypes: true}:

import { acceptsCallback, CallbackOptions } from 'external-dependency';

acceptsCallback((options: CallbackOptions) => {});
Open in Playground external-dependency.d.ts
export interface CallbackOptions {
prop: string;
}
type Callback = (options: CallbackOptions) => void;
type AcceptsCallback = (callback: Callback) => void;

export const acceptsCallback: AcceptsCallback;
import { acceptsCallback } from 'external-dependency';

acceptsCallback(options => {});
Open in Playground external-dependency.d.ts
export interface CallbackOptions {
prop: string;
}
type Callback = (options: CallbackOptions) => void;
type AcceptsCallback = (callback: Callback) => void;

export const acceptsCallback: AcceptsCallback;
treatMethodsAsReadonly

Whether to treat all mutable methods as though they are readonly. Default: false.

This may be desirable when you are never reassigning methods.

Examples of code for this rule with {treatMethodsAsReadonly: false}:

type MyType = {
readonly prop: string;
method(): string;
};
function foo(arg: MyType) {}
Open in Playground
type MyType = Readonly<{
prop: string;
method(): string;
}>;
function foo(arg: MyType) {}

type MyOtherType = {
readonly prop: string;
readonly method: () => string;
};
function bar(arg: MyOtherType) {}
Open in Playground

Examples of correct code for this rule with {treatMethodsAsReadonly: true}:

type MyType = {
readonly prop: string;
method(): string;
};
function foo(arg: MyType) {}
Open in Playground When Not To Use It

If your project does not attempt to enforce strong immutability guarantees of parameters, you can avoid this rule.

This rule is very strict on what it considers mutable. Many types that describe themselves as readonly are considered mutable because they have mutable properties such as arrays or tuples. To work around these limitations, you might need to use the rule's options. In particular, the allow option can explicitly mark a type as readonly.

Type checked lint rules are more powerful than traditional lint rules, but also require configuring type checked linting.

See Troubleshooting > Linting with Type Information > Performance if you experience performance degradations after enabling type checked rules.

Resources

RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4