❌ This rule is deprecated. It was replaced by functional/prefer-immutable-types
,functional/type-declaration-immutability
.
🚫 This rule is disabled in the disableTypeChecked
config.
🔧 This rule is automatically fixable by the --fix
CLI option.
💭 This rule requires type information.
This rule has been replaced by prefer-immutable-parameter-types and type-declaration-immutability.
This rule enforces use of readonly T[]
(ReadonlyArray<T>
) over T[]
(Array<T>
).
The readonly modifier must appear on property signatures in interfaces, property declarations in classes, and index signatures.
/* eslint functional/prefer-readonly-type: "error" */
interface Point {
x: number;
y: number;
}
const point: Point = { x: 23, y: 44 };
point.x = 99; // This is perfectly valid.
/* eslint functional/prefer-readonly-type: "error" */
interface Point {
readonly x: number;
readonly y: number;
}
const point: Point = { x: 23, y: 44 };
point.x = 99; // <- No object mutation allowed.
/* eslint functional/prefer-readonly-type: "error" */
interface Point {
readonly x: number;
readonly y: number;
}
const point: Point = { x: 23, y: 44 };
const transformedPoint = { ...point, x: 99 };
A variable declared as const
can not be reassigned, however what's in the variable can be mutated.
This is why the readonly
modifier exists. It prevents you from assigning a value to the result of a member expression.
This is just as effective as using Object.freeze()
to prevent mutations.
However the readonly
modifier has no run-time cost, and is enforced at compile time.
The readonly
modifier also works on indexers:
const foo: { readonly [key: string]: number } = { a: 1, b: 2 };
foo.a = 3; // Error: Index signature only permits reading
Even if an array is declared with const
it is still possible to mutate the contents of the array.
interface Point {
readonly x: number;
readonly y: number;
}
const points: Point[] = [{ x: 23, y: 44 }];
points.push({ x: 1, y: 2 }); // This is perfectly valid.
Using the ReadonlyArray<T>
type or readonly T[]
will stop this mutation:
interface Point {
readonly x: number;
readonly y: number;
}
const points: ReadonlyArray<Point> = [{ x: 23, y: 44 }];
// const points: readonly Point[] = [{ x: 23, y: 44 }]; // This is the alternative syntax for the line above
points.push({ x: 1, y: 2 }); // Unresolved method push()
This rule accepts an options object of the following type:
type Options = {
allowLocalMutation: boolean;
allowMutableReturnType: boolean;
checkImplicit: boolean;
ignoreClass: boolean | "fieldsOnly";
ignoreInterface: boolean;
ignoreCollections: boolean;
ignorePattern?: string[] | string;
};
const defaults = {
allowLocalMutation: false,
allowMutableReturnType: false,
checkImplicit: false,
ignoreClass: false,
ignoreInterface: false,
ignoreCollections: false,
};
By default, this function only checks explicit types. Enabling this option will make the rule also check implicit types.
Note: Checking implicit types is more expensive (slow).
Doesn't check the return type of functions.
A boolean to specify if checking for readonly
should apply to classes. false
by default.
/* eslint functional/prefer-readonly-type: ["error", { "ignoreClass": false }] */
class {
myprop: string;
}
/* eslint functional/prefer-readonly-type: ["error", { "ignoreClass": true }] */
class C {
myprop: string;
}
A boolean to specify if checking for readonly
should apply to interfaces. false
by default.
/* eslint functional/prefer-readonly-type: ["error", { "ignoreInterface": false }] */
interface I {
myprop: string;
}
/* eslint functional/prefer-readonly-type: ["error", { "ignoreInterface": true }] */
interface I {
myprop: string;
}
A boolean to specify if checking for readonly
should apply to mutable collections (Array, Tuple, Set, and Map).
Helpful for migrating from tslint-immutable to this plugin. false
by default.
/* eslint functional/prefer-readonly-type: ["error", { "ignoreCollections": false }] */
const foo: number[] = [];
const bar: [string, string] = ["foo", "bar"];
const baz: Set<string, string> = new Set();
const qux: Map<string, string> = new Map();
/* eslint functional/prefer-readonly-type: ["error", { "ignoreCollections": true }] */
const foo: number[] = [];
const bar: [string, string] = ["foo", "bar"];
const baz: Set<string, string> = new Set();
const qux: Map<string, string> = new Map();
If true
, local state is allowed to use non-readonly types. Local state is simply any code inside of a function.
This option takes a RegExp string or an array of RegExp strings. It allows for the ability to ignore violations based on a type's name.