New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

tslint-immutable

Package Overview
Dependencies
Maintainers
1
Versions
56
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

tslint-immutable - npm Package Compare versions

Comparing version 4.4.0 to 4.5.0

.nyc_output/160c6c7671ea81090a187a5431c010b3.json

192

CHANGELOG.md
# Change Log
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/)
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).

@@ -9,148 +10,223 @@

## [v4.5.0] - 2017-12-29
### Added
* New options `ignore-interface`, and `ignore-class` for the `readonly-keyword` rule. See [#44](https://github.com/jonaskello/tslint-immutable/issues/44) for background. Thanks to [@aboyton](https://github.com/aboyton) for these options! (See PR [#57](https://github.com/jonaskello/tslint-immutable/pull/57))
* The `ignore-prefix` option can be an array for all rules (previously just for `no-expression-statement` and `no-object-mutation`).
* New rule `no-delete`. See [readme](https://github.com/jonaskello/tslint-immutable#no-delete) for more info.
* New rule `no-if-statement`. See [readme](https://github.com/jonaskello/tslint-immutable#no-if-statement) for more info and [#54](https://github.com/jonaskello/tslint-immutable/issues/54) for discussion.
* New rule `no-loop-statement`. See [readme](https://github.com/jonaskello/tslint-immutable#no-loop-statement) for more info and [#54](https://github.com/jonaskello/tslint-immutable/issues/54) for discussion.
### Fixed
* `no-mixed-interface` does not understand arrow function notation. See [#60](https://github.com/jonaskello/tslint-immutable/issues/60).
## [v4.4.0] - 2017-09-27
### Added
- New option `ignore-prefix` for the `no-object-mutation` rule. See [#43](https://github.com/jonaskello/tslint-immutable/issues/43) for background. Thanks to [@miangraham](https://github.com/miangraham) for this option! (See PR [#53](https://github.com/jonaskello/tslint-immutable/pull/53))
* New option `ignore-prefix` for the `no-object-mutation` rule. See [#43](https://github.com/jonaskello/tslint-immutable/issues/43) for background. Thanks to [@miangraham](https://github.com/miangraham) for this option! (See PR [#53](https://github.com/jonaskello/tslint-immutable/pull/53))
## [v4.3.0] - 2017-09-23
### Fixed
- The readonly-keyword rule now properly checks for `readonly` modifier of `class` property declarations. See [#49](https://github.com/jonaskello/tslint-immutable/issues/49) and PR [#50](https://github.com/jonaskello/tslint-immutable/pull/50).
* The readonly-keyword rule now properly checks for `readonly` modifier of `class` property declarations. See [#49](https://github.com/jonaskello/tslint-immutable/issues/49) and PR [#50](https://github.com/jonaskello/tslint-immutable/pull/50).
### Added
- New rule [no-method-signature](https://github.com/jonaskello/tslint-immutable#no-method-signature). See [#30](https://github.com/jonaskello/tslint-immutable/issues/30) and PR in [#51](https://github.com/jonaskello/tslint-immutable/pull/51).
- New options `ignore-local`, and `ignore-prefix` for the `no-let` rule. See [#32](https://github.com/jonaskello/tslint-immutable/issues/32), also requested in [#43](https://github.com/jonaskello/tslint-immutable/issues/43). See PR [#48](https://github.com/jonaskello/tslint-immutable/pull/48).
- Added tslint core rule [no-parameter-reassignment](https://palantir.github.io/tslint/rules/no-parameter-reassignment/) as [recommended](https://github.com/jonaskello/tslint-immutable#no-parameter-reassignment) in the README.
* New rule [no-method-signature](https://github.com/jonaskello/tslint-immutable#no-method-signature). See [#30](https://github.com/jonaskello/tslint-immutable/issues/30) and PR in [#51](https://github.com/jonaskello/tslint-immutable/pull/51).
* New options `ignore-local`, and `ignore-prefix` for the `no-let` rule. See [#32](https://github.com/jonaskello/tslint-immutable/issues/32), also requested in [#43](https://github.com/jonaskello/tslint-immutable/issues/43). See PR [#48](https://github.com/jonaskello/tslint-immutable/pull/48).
* Added tslint core rule [no-parameter-reassignment](https://palantir.github.io/tslint/rules/no-parameter-reassignment/) as [recommended](https://github.com/jonaskello/tslint-immutable#no-parameter-reassignment) in the README.
## [v4.2.1] - 2017-09-21
### Fixed
- The readonly-array rule with ignore-local option does not work within `class`. See [45](https://github.com/jonaskello/tslint-immutable/issues/45).
* The readonly-array rule with ignore-local option does not work within `class`. See [45](https://github.com/jonaskello/tslint-immutable/issues/45).
## [v4.2.0] - 2017-09-14
### Added
- New option `ignore-prefix` for the `no-expression-statement` rule. See [#39](https://github.com/jonaskello/tslint-immutable/issues/39) for background. Thanks to [@algesten](https://github.com/algesten) for this option! (See PR [#42](https://github.com/jonaskello/tslint-immutable/pull/42))
* New option `ignore-prefix` for the `no-expression-statement` rule. See [#39](https://github.com/jonaskello/tslint-immutable/issues/39) for background. Thanks to [@algesten](https://github.com/algesten) for this option! (See PR [#42](https://github.com/jonaskello/tslint-immutable/pull/42))
## [v4.1.0] - 2017-08-21
### Added
- New rule `no-object-mutation`. See [#36](https://github.com/jonaskello/tslint-immutable/issues/36) for background. Thanks to [@miangraham](https://github.com/miangraham) for this rule! (See PR [#37](https://github.com/jonaskello/tslint-immutable/pull/37))
* New rule `no-object-mutation`. See [#36](https://github.com/jonaskello/tslint-immutable/issues/36) for background. Thanks to [@miangraham](https://github.com/miangraham) for this rule! (See PR [#37](https://github.com/jonaskello/tslint-immutable/pull/37))
## [v4.0.2] - 2017-07-16
### Added
- Added an index.js file to the rules directory in order for rulesDirectory to work. See [#35](https://github.com/jonaskello/tslint-immutable/issues/35).
* Added an index.js file to the rules directory in order for rulesDirectory to work. See [#35](https://github.com/jonaskello/tslint-immutable/issues/35).
## [v4.0.1] - 2017-06-06
### Fixed
- Invalid default tslint config (it included the removed rules).
* Invalid default tslint config (it included the removed rules).
## [v4.0.0] - 2017-06-06
### Removed
- `readonly-interface` rule. This rule is replaced by the `readonly-keyword` rule.
- `readonly-indexer` rule. This rule is replaced by the `readonly-keyword` rule.
- `no-new` rule. Please see background in [#2](https://github.com/jonaskello/tslint-immutable/issues/2).
- `no-arguments` rule. This rule has been moved to the [tslint-divid](https://www.npmjs.com/package/tslint-divid) package.
- `no-label` rule. This rule has been moved to the [tslint-divid](https://www.npmjs.com/package/tslint-divid) package.
- `no-semicolon-interface` rule. This rule has been moved to the [tslint-divid](https://www.npmjs.com/package/tslint-divid) package.
- `import-containment` rule. This rule has been moved to the [tslint-divid](https://www.npmjs.com/package/tslint-divid) package.
* `readonly-interface` rule. This rule is replaced by the `readonly-keyword` rule.
* `readonly-indexer` rule. This rule is replaced by the `readonly-keyword` rule.
* `no-new` rule. Please see background in [#2](https://github.com/jonaskello/tslint-immutable/issues/2).
* `no-arguments` rule. This rule has been moved to the [tslint-divid](https://www.npmjs.com/package/tslint-divid) package.
* `no-label` rule. This rule has been moved to the [tslint-divid](https://www.npmjs.com/package/tslint-divid) package.
* `no-semicolon-interface` rule. This rule has been moved to the [tslint-divid](https://www.npmjs.com/package/tslint-divid) package.
* `import-containment` rule. This rule has been moved to the [tslint-divid](https://www.npmjs.com/package/tslint-divid) package.
## [v3.4.2] - 2017-05-14
### Added
- Notice in readme about deprecrating the `no-new` rule.
* Notice in readme about deprecrating the `no-new` rule.
### Deprecated
- The `no-new` rule. See [#2](https://github.com/jonaskello/tslint-immutable/issues/2) for background.
* The `no-new` rule. See [#2](https://github.com/jonaskello/tslint-immutable/issues/2) for background.
## [v3.4.1] - 2017-05-14
### Added
- Note in readme about moving the "other" rules. The `no-argument`, `no-label`, `no-semicolon-interface`, and `import containtment` rules are moving to [tslint-divid](https://github.com/jonaskello/tslint-divid). See [#19](https://github.com/jonaskello/tslint-immutable/issues/19) for more information.
* Note in readme about moving the "other" rules. The `no-argument`, `no-label`, `no-semicolon-interface`, and `import containtment` rules are moving to [tslint-divid](https://github.com/jonaskello/tslint-divid). See [#19](https://github.com/jonaskello/tslint-immutable/issues/19) for more information.
### Deprecated
- The `no-argument`, `no-label`, `no-semicolon-interface`, and `import containtment` rules as noted above.
* The `no-argument`, `no-label`, `no-semicolon-interface`, and `import containtment` rules as noted above.
## [v3.4.0] - 2017-05-14
### Added
- New rule `readonly-keyword`, to replace `readonly-interface` and `readonly-indexer` [#31](https://github.com/jonaskello/tslint-immutable/issues/31)
* New rule `readonly-keyword`, to replace `readonly-interface` and `readonly-indexer` [#31](https://github.com/jonaskello/tslint-immutable/issues/31)
### Deprecated
- The `readonly-interface`, and `readonly-indexer` rules are deprecated and will be removed in the next major release. Please use the `readonly-keyword` rule instead.
* The `readonly-interface`, and `readonly-indexer` rules are deprecated and will be removed in the next major release. Please use the `readonly-keyword` rule instead.
## [v3.3.2] - 2017-05-13
### Fixed
- Functions in interfaces cannot have readonly specified but are still checked [#28](https://github.com/jonaskello/tslint-immutable/issues/28)
* Functions in interfaces cannot have readonly specified but are still checked [#28](https://github.com/jonaskello/tslint-immutable/issues/28)
## [v3.3.1] - 2017-05-09
### Fixed
- patch: fix main file in package.json. Thanks to [@yonbeastie](https://github.com/yonbeastie). (see [#29](https://github.com/jonaskello/tslint-immutable/pull/29))
* patch: fix main file in package.json. Thanks to [@yonbeastie](https://github.com/yonbeastie). (see [#29](https://github.com/jonaskello/tslint-immutable/pull/29))
## [v3.3.0] - 2017-05-09
### Fixed
- ignore-local does not work for function assigned to const [#23](https://github.com/jonaskello/tslint-immutable/issues/23)
* ignore-local does not work for function assigned to const [#23](https://github.com/jonaskello/tslint-immutable/issues/23)
### Added
- Add default tslint json. Thanks to [@yonbeastie](https://github.com/yonbeastie). (see [#26](https://github.com/jonaskello/tslint-immutable/pull/26))
* Add default tslint json. Thanks to [@yonbeastie](https://github.com/yonbeastie). (see [#26](https://github.com/jonaskello/tslint-immutable/pull/26))
## [v3.2.0] - 2017-04-10
### Fixed
- readonly-array does not check shorthand syntax in return types with ignore-local option [#21](https://github.com/jonaskello/tslint-immutable/issues/21)
* readonly-array does not check shorthand syntax in return types with ignore-local option [#21](https://github.com/jonaskello/tslint-immutable/issues/21)
### Added
- Fixer for the `readonly-array` rule.
* Fixer for the `readonly-array` rule.
## [v3.1.2] - 2017-04-09
### Fixed
- readonly-array does not check return type when ignore-local is enabled [#16](https://github.com/jonaskello/tslint-immutable/issues/16)
- readonly-array does not check shorthand syntax [#20](https://github.com/jonaskello/tslint-immutable/issues/20).
* readonly-array does not check return type when ignore-local is enabled [#16](https://github.com/jonaskello/tslint-immutable/issues/16)
* readonly-array does not check shorthand syntax [#20](https://github.com/jonaskello/tslint-immutable/issues/20).
## Changed
- Impicit return type is not checked in readonly-array [#18](https://github.com/jonaskello/tslint-immutable/issues/18).
* Impicit return type is not checked in readonly-array [#18](https://github.com/jonaskello/tslint-immutable/issues/18).
## [v3.1.1] - 2017-04-05
### Fixed
- Function parameters are not checked when using ignore-local option, [#13](https://github.com/jonaskello/tslint-immutable/issues/13).
- Implicit Array type by default value for function parameter is not checked, [#14](https://github.com/jonaskello/tslint-immutable/issues/14).
* Function parameters are not checked when using ignore-local option, [#13](https://github.com/jonaskello/tslint-immutable/issues/13).
* Implicit Array type by default value for function parameter is not checked, [#14](https://github.com/jonaskello/tslint-immutable/issues/14).
## [v3.1.0] - 2017-04-05
### Added
- [`ignore-local`](https://github.com/jonaskello/tslint-immutable#using-the-ignore-local-option) option added to `readonly-array`.
- [`ignore-prefix`](https://github.com/jonaskello/tslint-immutable#using-the-ignore-local-option) option added to `readonly-array`.
* [`ignore-local`](https://github.com/jonaskello/tslint-immutable#using-the-ignore-local-option) option added to `readonly-array`.
* [`ignore-prefix`](https://github.com/jonaskello/tslint-immutable#using-the-ignore-local-option) option added to `readonly-array`.
## [v3.0.0] - 2017-04-02
### Changed
- Upgraded to tslint 5.0.0
* Upgraded to tslint 5.0.0
### Added
- `readonly-array` now also checks for implicity declared mutable arrays.
* `readonly-array` now also checks for implicity declared mutable arrays.
## [v2.1.1] - 2017-03-29
### Fixed
- Remove vestigial `noMutationRule.js` and `no-mutation` example from README, thanks to [@pmlamotte](https://github.com/pmlamotte). (see [#6](https://github.com/jonaskello/tslint-immutable/pull/6))
* Remove vestigial `noMutationRule.js` and `no-mutation` example from README, thanks to [@pmlamotte](https://github.com/pmlamotte). (see [#6](https://github.com/jonaskello/tslint-immutable/pull/6))
## [v2.1.0] - 2016-12-12
### Added
- `readonly-indexer` rule.
* `readonly-indexer` rule.
### Fixed
- Fixed a bug in `readonly-interface` rule that made it fail on indexer declarations.
* Fixed a bug in `readonly-interface` rule that made it fail on indexer declarations.
## [v2.0.0] - 2016-12-12
### Added
- `readonly-interface` rule.
- `readonly-indexer` rule.
- `readonly-array` rule.
- `no-class` rule.
- `no-new` rule.
- `no-mixed-interface` rule.
- `import-containment` rule.
- `no-arguments` rule.
- `no-label` rule.
- `no-semicolon-interface` rule.
* `readonly-interface` rule.
* `readonly-indexer` rule.
* `readonly-array` rule.
* `no-class` rule.
* `no-new` rule.
* `no-mixed-interface` rule.
* `import-containment` rule.
* `no-arguments` rule.
* `no-label` rule.
* `no-semicolon-interface` rule.
### Removed
- `no-mutation` rule (replaced by the `readonly-interface` rule).
* `no-mutation` rule (replaced by the `readonly-interface` rule).
## v1.0.0 - 2016-12-10
### Added
- `no-expression-statement` rule.
- `no-let` rule.
- `no-mutation` rule.
- `no-this` rule.
[Unreleased]: https://github.com/jonaskello/tslint-immutable/compare/v4.4.0...master
* `no-expression-statement` rule.
* `no-let` rule.
* `no-mutation` rule.
* `no-this` rule.
[unreleased]: https://github.com/jonaskello/tslint-immutable/compare/v4.5.0...master
[v4.4.0]: https://github.com/jonaskello/tslint-immutable/compare/v4.4.0...v4.5.0
[v4.4.0]: https://github.com/jonaskello/tslint-immutable/compare/v4.3.0...v4.4.0

@@ -157,0 +233,0 @@ [v4.3.0]: https://github.com/jonaskello/tslint-immutable/compare/v4.2.1...v4.3.0

{
"name": "tslint-immutable",
"version": "4.4.0",
"version": "4.5.0",
"description": "TSLint rules to disable mutation in TypeScript.",

@@ -21,14 +21,19 @@ "main": "tslint-immutable.json",

"devDependencies": {
"@types/node": "^8.0.53",
"coveralls": "^2.13.1",
"husky": "^0.14.3",
"lint-staged": "^5.0.0",
"nyc": "^11.2.1",
"prettier": "^1.9.2",
"shelljs": "^0.7.5",
"tslint": "^5.1.0",
"tslint-plugin-prettier": "^1.3.0",
"typescript": "^2.2.2"
},
"scripts": {
"tsc": "tsc",
"compile": "tsc",
"build": "rm -rf rules && tsc -p tsconfig.json",
"lint": "tslint './src/**/*.ts{,x}'",
"test": "tslint --test test/rules/**/*",
"test:work": "yarn build && tslint --test test/rules/no-method-signature/*",
"test:work": "yarn build && tslint --test test/rules/readonly-keyword/work/*",
"verify": "yarn build && yarn lint && yarn coverage",

@@ -40,3 +45,10 @@ "coverage": "rm -rf coverage .nyc_output && nyc yarn test",

"publish:patch": "npm run build && node scripts/publish.js patch"
},
"lint-staged": {
"*.{ts,tsx}": "tslint",
"*.{ts,tsx,json,css}": [
"prettier --write",
"git add"
]
}
}

@@ -6,5 +6,6 @@ # tslint-immutable

[![Coverage Status][coveralls-image]][coveralls-url]
[![code style: prettier][prettier-image]][prettier-url]
[![MIT license][license-image]][license-url]
[TSLint](https://palantir.github.io/tslint/) rules to disable mutation in TypeScript.
[TSLint](https://palantir.github.io/tslint/) rules to disable mutation in TypeScript.

@@ -35,3 +36,3 @@ ## Background

In addition to immutable rules this project also contains a few rules for enforcing a functional style of programming and a few other rules. The following rules are available:
In addition to immutable rules this project also contains a few rules for enforcing a functional style of programming. The following rules are available:

@@ -44,2 +45,3 @@ * [Immutability rules](#immutability-rules)

* [no-method-signature](#no-method-signature)
* [no-delete](#no-delete)
* [Functional style rules](#functional-style-rules)

@@ -50,2 +52,4 @@ * [no-this](#no-this-no-class)

* [no-expression-statement](#no-expression-statement)
* [no-if-statement](#no-if-statement)
* [no-loop-statement](#no-loop-statement)
* [Recommended built-in rules](#recommended-built-in-rules)

@@ -57,3 +61,3 @@

This rule enforces use of the `readonly` modifier. The `readonly` modifier can appear on property signatures in interfaces, property declarations in classes, and index signatures.
This rule enforces use of the `readonly` modifier. The `readonly` modifier can appear on property signatures in interfaces, property declarations in classes, and index signatures.

@@ -65,3 +69,6 @@ Below is some information about the `readonly` modifier and the benefits of using it:

```typescript
interface Point { x: number, y: number }
interface Point {
x: number;
y: number;
}
const point: Point = { x: 23, y: 44 };

@@ -74,3 +81,6 @@ point.x = 99; // This is legal

```typescript
interface Point { readonly x: number, readonly y: number }
interface Point {
readonly x: number;
readonly y: number;
}
const point: Point = { x: 23, y: 44 };

@@ -80,6 +90,9 @@ point.x = 99; // <- No object mutation allowed.

This is just as effective as using Object.freeze() to prevent mutations in your Redux reducers. However the `readonly` modifier has **no run-time cost**, and is enforced at **compile time**. A good alternative to object mutation is to use the ES2016 object spread [syntax](https://github.com/Microsoft/TypeScript/wiki/What's-new-in-TypeScript#object-spread-and-rest) that was added in typescript 2.1:
This is just as effective as using Object.freeze() to prevent mutations in your Redux reducers. However the `readonly` modifier has **no run-time cost**, and is enforced at **compile time**. A good alternative to object mutation is to use the ES2016 object spread [syntax](https://github.com/Microsoft/TypeScript/wiki/What's-new-in-TypeScript#object-spread-and-rest) that was added in typescript 2.1:
```typescript
interface Point { readonly x: number, readonly y: number }
interface Point {
readonly x: number;
readonly y: number;
}
const point: Point = { x: 23, y: 44 };

@@ -98,3 +111,3 @@ const transformedPoint = { ...point, x: 99 };

```typescript
const foo: { readonly [key: string]: number } = { "a": 1, "b": 2 };
const foo: { readonly [key: string]: number } = { a: 1, b: 2 };
foo["a"] = 3; // Error: Index signature only permits reading

@@ -104,15 +117,22 @@ ```

#### Has Fixer
Yes
#### Options
- [ignore-local](#using-the-ignore-local-option)
- [ignore-prefix](#using-the-ignore-prefix-option)
* [ignore-local](#using-the-ignore-local-option)
* [ignore-class](#using-the-ignore-class-option)
* [ignore-interface](#using-the-ignore-interface-option)
* [ignore-prefix](#using-the-ignore-prefix-option)
#### Example config
```javascript
"readonly-keyword": true
```
```javascript
"readonly-keyword": [true, "ignore-local"]
```
```javascript

@@ -131,3 +151,6 @@ "readonly-keyword": [true, "ignore-local", {"ignore-prefix": "mutable"}]

```typescript
interface Point { readonly x: number, readonly y: number }
interface Point {
readonly x: number;
readonly y: number;
}
const points: Array<Point> = [{ x: 23, y: 44 }];

@@ -140,3 +163,6 @@ points.push({ x: 1, y: 2 }); // This is legal

```typescript
interface Point { readonly x: number, readonly y: number }
interface Point {
readonly x: number;
readonly y: number;
}
const points: ReadonlyArray<Point> = [{ x: 23, y: 44 }];

@@ -147,15 +173,20 @@ points.push({ x: 1, y: 2 }); // Unresolved method push()

#### Has Fixer
Yes
#### Options
- [ignore-local](#using-the-ignore-local-option)
- [ignore-prefix](#using-the-ignore-prefix-option)
* [ignore-local](#using-the-ignore-local-option)
* [ignore-prefix](#using-the-ignore-prefix-option)
#### Example config
```javascript
"readonly-array": true
```
```javascript
"readonly-array": [true, "ignore-local"]
```
```javascript

@@ -166,2 +197,3 @@ "readonly-array": [true, "ignore-local", {"ignore-prefix": "mutable"}]

### no-let
This rule should be combined with tslint's built-in `no-var-keyword` rule to enforce that all variables are declared as `const`.

@@ -178,23 +210,29 @@

```typescript
const SearchResults =
({ results }) =>
<ul>{
results.map(result => <li>result</li>) // <- Who needs let?
}</ul>;
const SearchResults = ({ results }) => (
<ul>
{results.map(result => <li>result</li>) // <- Who needs let?
}
</ul>
);
```
#### Has Fixer
Yes
#### Options
- [ignore-local](#using-the-ignore-local-option)
- [ignore-prefix](#using-the-ignore-prefix-option)
* [ignore-local](#using-the-ignore-local-option)
* [ignore-prefix](#using-the-ignore-prefix-option)
#### Example config
```javascript
"no-let": true
```
```javascript
"no-let": [true, "ignore-local"]
```
```javascript

@@ -205,8 +243,9 @@ "no-let": [true, "ignore-local", {"ignore-prefix": "mutable"}]

### no-object-mutation
This rule prohibits syntax that mutates existing objects via assignment to or deletion of their properties. While requiring the `readonly` modifier forces declared types to be immutable, it won't stop assignment into or modification of untyped objects or external types declared under different rules. Forbidding forms like `a.b = 'c'` is one way to plug this hole. Inspired by the no-mutation rule of [eslint-plugin-immutable](https://github.com/jhusain/eslint-plugin-immutable).
```typescript
const x = {a: 1};
const x = { a: 1 };
x.foo = 'bar'; // <- Modifying properties of existing object not allowed.
x.foo = "bar"; // <- Modifying properties of existing object not allowed.
x.a += 1; // <- Modifying properties of existing object not allowed.

@@ -216,3 +255,22 @@ delete x.a; // <- Modifying properties of existing object not allowed.

#### Has Fixer
No
#### Options
* [ignore-prefix](#using-the-ignore-prefix-option)
#### Example config
```javascript
"no-object-mutation": true
```
```javascript
"no-object-mutation": [true, {"ignore-prefix": "mutable"}]
```
### no-method-signature
There are two ways function members can be declared in an interface or type alias:

@@ -222,4 +280,4 @@

interface Zoo {
foo(): string, // MethodSignature, cannot have readonly modifier
readonly bar: () => string, // PropertySignature
foo(): string; // MethodSignature, cannot have readonly modifier
readonly bar: () => string; // PropertySignature
}

@@ -230,5 +288,20 @@ ```

### no-delete
The delete operator allows for mutating objects by deleting keys. This rule disallows any delete expressions.
```typescript
delete object.property; // Unexpected delete, objects should be considered immutable.
```
As an alternative the spread operator can be used to delete a key in an object (as noted [here](https://stackoverflow.com/a/35676025/2761797)):
```typescript
const { [action.id]: deletedItem, ...rest } = state;
```
## Functional style rules
### no-this, no-class
Thanks to libraries like [recompose](https://github.com/acdlite/recompose) and Redux's [React Container components](http://redux.js.org/docs/basics/UsageWithReact.html), there's not much reason to build Components using `React.createClass` or ES6 classes anymore. The `no-this` rule makes this explicit.

@@ -239,10 +312,11 @@

render: function() {
return <div>{ this.props.message }</div>; // <- no this allowed
return <div>{this.props.message}</div>; // <- no this allowed
}
})
});
```
Instead of creating classes, you should use React 0.14's [Stateless Functional Components](https://medium.com/@joshblack/stateless-components-in-react-0-14-f9798f8b992d#.t5z2fdit6) and save yourself some keystrokes:
```typescript
const Message = ({message}) => <div>{ message }</div>;
const Message = ({ message }) => <div>{message}</div>;
```

@@ -253,5 +327,5 @@

```typescript
import { pure, onlyUpdateForKeys } from 'recompose';
import { pure, onlyUpdateForKeys } from "recompose";
const Message = ({message}) => <div>{ message }</div>;
const Message = ({ message }) => <div>{message}</div>;

@@ -263,3 +337,3 @@ // Optimized version of same component, using shallow comparison of props

// Even more optimized: only updates if specific prop keys have changed
const HyperOptimizedMessage = onlyUpdateForKeys(['message'], Message);
const HyperOptimizedMessage = onlyUpdateForKeys(["message"], Message);
```

@@ -269,10 +343,11 @@

Mixing functions and data properties in the same interface is a sign of object-orientation style. This rule enforces that an inteface only has one type of members, eg. only data properties or only functions.
Mixing functions and data properties in the same interface is a sign of object-orientation style. This rule enforces that an inteface only has one type of members, eg. only data properties or only functions.
### no-expression-statement
When you call a function and don’t use it’s return value, chances are high that it is being called for its side effect. e.g.
```typescript
array.push(1)
alert('Hello world!')
array.push(1);
alert("Hello world!");
```

@@ -283,4 +358,5 @@

#### Options
- [ignore-prefix](#using-the-ignore-prefix-option-with-no-expression-statement)
* [ignore-prefix](#using-the-ignore-prefix-option-with-no-expression-statement)
#### Example config

@@ -300,2 +376,44 @@

### no-if-statement
If statements is not a good fit for functional style programming as they are not expresssions and do not return a value. This rule disallows if statements.
```typescript
let x;
if (i === 1) {
x = 2;
} else {
x = 3;
}
```
Instead consider using the [tenary operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_Operator) which is an expression that returns a value:
```typescript
const x = i === 1 ? 2 : 3;
```
For more background see this [blog post](https://hackernoon.com/rethinking-javascript-the-if-statement-b158a61cd6cb) and discussion in [#54](https://github.com/jonaskello/tslint-immutable/issues/54).
### no-loop-statement
In functional programming we want everthing to be an expression that returns a value. Loops in typescript are statements so they are not a good fit for a functional programming style. This rule disallows for loop statements, including `for`, `for...of`, `for...in`, `while`, and `do...while`.
```typescript
const numbers = [1, 2, 3];
const double = [];
for (let i = 0; i < numbers.length; i++) {
double[i] = numbers[i] * 2;
}
```
Instead consider using `map` or `reduce`:
```typescript
const numbers = [1, 2, 3];
const double = numbers.map(n => n * 2);
```
For more background see this [blog post](https://hackernoon.com/rethinking-javascript-death-of-the-for-loop-c431564c84a8) and discussion in [#54](https://github.com/jonaskello/tslint-immutable/issues/54).
## Options

@@ -312,2 +430,10 @@

### Using the `ignore-class` option
Doesn't check for `readonly` in classes.
### Using the `ignore-interface` option
Doesn't check for `readonly` in interfaces.
### Using the `ignore-prefix` option

@@ -328,4 +454,4 @@

type person = {
readonly name: string,
mutableAge: number // This is OK with ignore-prefix = "mutable"
readonly name: string;
mutableAge: number; // This is OK with ignore-prefix = "mutable"
};

@@ -400,2 +526,4 @@ ```

"no-object-mutation": true,
"no-delete": true,
"no-method-signature": true,

@@ -406,3 +534,4 @@ // Functional style rules

"no-mixed-interface": true,
"no-expression-statement": true,
"no-expression-statement": true
"no-if-statement": true

@@ -419,6 +548,10 @@ }

To execute the tests first run `yarn build` and then run `yarn test`.
To execute the tests first run `yarn build` and then run `yarn test`.
While working on the code you can run `yarn test:work`. This script also builds before running the tests. To run a subset of the tests, change the path for `yarn test:work` in `package.json.
While working on the code you can run `yarn test:work`. This script also builds before running the tests. To run a subset of the tests, change the path for `yarn test:work` in `package.json`.
Please review the [tslint performance tips](https://palantir.github.io/tslint/develop/custom-rules/performance-tips.html) in order to write rules that run efficiently at run-time. For example, note that using `SyntaxWalker` or any subclass thereof like `RuleWalker` is inefficient. Note that tslint requires the use of `class` as an entrypoint, but you can make a very small class that inherits from `AbstractRule` which directly calls `this.applyWithFunction` and from there you can switch to using a more functional programming style.
In order to know which AST nodes are created for a snippet of typescript code you can use [ast explorer](https://astexplorer.net/).
To release a new package version run `yarn publish:patch`, `yarn publish:minor`, or `yarn publish:major`.

@@ -438,2 +571,3 @@

[license-url]: https://opensource.org/licenses/MIT
[prettier-image]: https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat
[prettier-url]: https://github.com/prettier/prettier
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var ts = require("typescript");
var Lint = require("tslint");
var Rule = (function (_super) {
__extends(Rule, _super);
function Rule() {
return _super !== null && _super.apply(this, arguments) || this;
}
Rule.prototype.apply = function (sourceFile) {
var noClassKeywordWalker = new NoClassWalker(sourceFile, this.getOptions());
return this.applyWithWalker(noClassKeywordWalker);
};
return Rule;
}(Lint.Rules.AbstractRule));
Rule.FAILURE_STRING = "Unexpected class, use functions not classes.";
exports.Rule = Rule;
var NoClassWalker = (function (_super) {
__extends(NoClassWalker, _super);
function NoClassWalker() {
return _super !== null && _super.apply(this, arguments) || this;
}
NoClassWalker.prototype.visitNode = function (node) {
if (node && node.kind === ts.SyntaxKind.ClassKeyword || node.kind === ts.SyntaxKind.ClassDeclaration) {
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), Rule.FAILURE_STRING));
}
_super.prototype.visitNode.call(this, node);
};
return NoClassWalker;
}(Lint.RuleWalker));
var check_node_1 = require("./shared/check-node");
// tslint:disable-next-line:variable-name
exports.Rule = check_node_1.createCheckNodeRule(checkNode, "Unexpected class, use functions not classes.");
function checkNode(node, _ctx) {
return node &&
(node.kind === ts.SyntaxKind.ClassKeyword ||
node.kind === ts.SyntaxKind.ClassDeclaration)
? { invalidNodes: [check_node_1.createInvalidNode(node)] }
: {
invalidNodes: []
};
}
//# sourceMappingURL=noClassRule.js.map
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var ts = require("typescript");
var Lint = require("tslint");
var OPTION_IGNORE_PREFIX = "ignore-prefix";
function parseOptions(options) {
var ignorePrefix;
for (var _i = 0, options_1 = options; _i < options_1.length; _i++) {
var o = options_1[_i];
if (typeof o === "object" && o[OPTION_IGNORE_PREFIX] !== null) {
ignorePrefix = o[OPTION_IGNORE_PREFIX];
break;
var check_node_1 = require("./shared/check-node");
var Ignore = require("./shared/ignore");
// tslint:disable-next-line:variable-name
exports.Rule = check_node_1.createCheckNodeRule(checkNode, "Using expressions to cause side-effects not allowed.");
function checkNode(node, ctx) {
if (node && node.kind === ts.SyntaxKind.ExpressionStatement) {
var children = node.getChildren();
var text = node.getText(node.getSourceFile());
var isYield = children.every(function (n) { return n.kind === ts.SyntaxKind.YieldExpression; });
var isIgnored2 = Ignore.isIgnoredPrefix(text, ctx.options.ignorePrefix);
if (!isYield && !isIgnored2) {
return { invalidNodes: [check_node_1.createInvalidNode(node)] };
}
}
return { ignorePrefix: ignorePrefix };
return { invalidNodes: [] };
}
var Rule = (function (_super) {
__extends(Rule, _super);
function Rule() {
return _super !== null && _super.apply(this, arguments) || this;
}
Rule.prototype.apply = function (sourceFile) {
var noExpressionStatementWalker = new NoExpressionStatementWalker(sourceFile, this.getOptions());
return this.applyWithWalker(noExpressionStatementWalker);
};
return Rule;
}(Lint.Rules.AbstractRule));
Rule.FAILURE_STRING = "Using expressions to cause side-effects not allowed.";
exports.Rule = Rule;
var NoExpressionStatementWalker = (function (_super) {
__extends(NoExpressionStatementWalker, _super);
function NoExpressionStatementWalker(sourceFile, options) {
var _this = _super.call(this, sourceFile, options) || this;
Object.assign(_this, parseOptions(options.ruleArguments));
return _this;
}
NoExpressionStatementWalker.prototype.visitNode = function (node) {
if (node && node.kind === ts.SyntaxKind.ExpressionStatement) {
var children = node.getChildren();
var text = node.getText(this.getSourceFile());
var isYield = children.every(function (n) { return n.kind === ts.SyntaxKind.YieldExpression; });
var isIgnored = this.isIgnored(text);
if (!isYield && !isIgnored) {
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), Rule.FAILURE_STRING));
}
}
_super.prototype.visitNode.call(this, node);
};
NoExpressionStatementWalker.prototype.isIgnored = function (text) {
if (!this.ignorePrefix) {
return false;
}
if (Array.isArray(this.ignorePrefix)) {
if (this.ignorePrefix.find(function (pfx) { return text.indexOf(pfx) === 0; })) {
return true;
}
}
else {
if (text.indexOf(this.ignorePrefix) === 0) {
return true;
}
}
return false;
};
return NoExpressionStatementWalker;
}(Lint.RuleWalker));
//# sourceMappingURL=noExpressionStatementRule.js.map
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var ts = require("typescript");
var Lint = require("tslint");
var Shared = require("./readonly-shared");
var Rule = (function (_super) {
__extends(Rule, _super);
function Rule() {
return _super !== null && _super.apply(this, arguments) || this;
}
Rule.prototype.apply = function (sourceFile) {
return this.applyWithFunction(sourceFile, function (ctx) {
return Shared.walk(ctx, checkNode, "Unexpected let, use const instead.");
}, Shared.parseOptions(this.ruleArguments));
};
return Rule;
}(Lint.Rules.AbstractRule));
exports.Rule = Rule;
var Ignore = require("./shared/ignore");
var check_node_1 = require("./shared/check-node");
// tslint:disable-next-line:variable-name
exports.Rule = check_node_1.createCheckNodeRule(Ignore.checkNodeWithIgnore(checkNode), "Unexpected let, use const instead.");
function checkNode(node, ctx) {
var variableStatementFailures = chectVariableStatement(node, ctx);
var forStatementsFailures = checkForStatements(node, ctx);
return variableStatementFailures.concat(forStatementsFailures);
return {
invalidNodes: variableStatementFailures.concat(forStatementsFailures)
};
}

@@ -69,4 +51,4 @@ function chectVariableStatement(node, ctx) {

var variableDeclarationNode = _a[_i];
if (!Shared.shouldIgnorePrefix(variableDeclarationNode, ctx.options, ctx.sourceFile)) {
invalidVariableDeclarationNodes.push(Shared.createInvalidNode(variableDeclarationNode, addFix
if (!Ignore.shouldIgnorePrefix(variableDeclarationNode, ctx.options, ctx.sourceFile)) {
invalidVariableDeclarationNodes.push(check_node_1.createInvalidNode(variableDeclarationNode, addFix
? new Lint.Replacement(declarationList.getStart(ctx.sourceFile), "let".length, "const")

@@ -73,0 +55,0 @@ : undefined));

"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var ts = require("typescript");
var Lint = require("tslint");
var Rule = (function (_super) {
__extends(Rule, _super);
function Rule() {
return _super !== null && _super.apply(this, arguments) || this;
}
Rule.prototype.apply = function (sourceFile) {
var noThisKeywordWalker = new NoMethodSignatureWalker(sourceFile, this.getOptions());
return this.applyWithWalker(noThisKeywordWalker);
};
return Rule;
}(Lint.Rules.AbstractRule));
Rule.FAILURE_STRING = "Method signature is mutable, use property signature with readonly modifier instead.";
exports.Rule = Rule;
var NoMethodSignatureWalker = (function (_super) {
__extends(NoMethodSignatureWalker, _super);
function NoMethodSignatureWalker() {
return _super !== null && _super.apply(this, arguments) || this;
}
NoMethodSignatureWalker.prototype.visitNode = function (node) {
if (node && node.kind === ts.SyntaxKind.MethodSignature) {
this.addFailureAtNode(node, Rule.FAILURE_STRING);
}
_super.prototype.visitNode.call(this, node);
};
return NoMethodSignatureWalker;
}(Lint.RuleWalker));
var check_node_1 = require("./shared/check-node");
// tslint:disable-next-line:variable-name
exports.Rule = check_node_1.createCheckNodeRule(checkNode, "Method signature is mutable, use property signature with readonly modifier instead.");
function checkNode(node, _ctx) {
return node && node.kind === ts.SyntaxKind.MethodSignature
? { invalidNodes: [check_node_1.createInvalidNode(node)] }
: {
invalidNodes: []
};
}
//# sourceMappingURL=noMethodSignatureRule.js.map
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var Lint = require("tslint");
var Rule = (function (_super) {
__extends(Rule, _super);
function Rule() {
return _super !== null && _super.apply(this, arguments) || this;
}
Rule.prototype.apply = function (sourceFile) {
var walker = new PropertyInterfaceWalker(sourceFile, this.getOptions());
return this.applyWithWalker(walker);
};
return Rule;
}(Lint.Rules.AbstractRule));
Rule.FAILURE_STRING = "Only the same kind of members allowed in interfaces.";
exports.Rule = Rule;
var PropertyInterfaceWalker = (function (_super) {
__extends(PropertyInterfaceWalker, _super);
function PropertyInterfaceWalker() {
return _super !== null && _super.apply(this, arguments) || this;
}
PropertyInterfaceWalker.prototype.visitInterfaceDeclaration = function (node) {
// Extract 'kind' from all members to a list of numbers.
var memberKinds = node.members.map(function (m) { return m.kind; });
// Check so all members of a node have the same kind,
var unUniqueMember = uniqIndex(memberKinds);
if (unUniqueMember !== -1) {
this.addFailure(this.createFailure(node.members[unUniqueMember].getStart(), node.members[unUniqueMember].getWidth(), Rule.FAILURE_STRING));
var ts = require("typescript");
var check_node_1 = require("./shared/check-node");
// tslint:disable-next-line:variable-name
exports.Rule = check_node_1.createCheckNodeRule(checkNode, "Only the same kind of members allowed in interfaces.");
function checkNode(node, _ctx) {
var invalidNodes = [];
if (node.kind === ts.SyntaxKind.InterfaceDeclaration) {
var interfaceDeclaration = node;
var prevMemberKind = undefined;
var prevMemberType = undefined;
for (var _i = 0, _a = interfaceDeclaration.members; _i < _a.length; _i++) {
var member = _a[_i];
var memberKind = member.kind;
var memberType = 0;
// If it is a property declaration we need to check the type too
if (member.kind === ts.SyntaxKind.PropertySignature) {
var propertySignature = member;
// Special care for function type
if (propertySignature.type &&
propertySignature.type.kind === ts.SyntaxKind.FunctionType) {
// We only set memberType for Functions
memberType = propertySignature.type.kind;
}
}
if (prevMemberKind !== undefined &&
(prevMemberKind !== memberKind || prevMemberType !== memberType)) {
invalidNodes.push(check_node_1.createInvalidNode(member));
}
prevMemberKind = memberKind;
prevMemberType = memberType;
}
_super.prototype.visitInterfaceDeclaration.call(this, node);
};
return PropertyInterfaceWalker;
}(Lint.RuleWalker));
/**
* Return the index of the first non unique item.
*
*/
function uniqIndex(list) {
var i = 0;
var lastItem = undefined;
for (var _i = 0, list_1 = list; _i < list_1.length; _i++) {
var item = list_1[_i];
if (lastItem !== undefined && lastItem !== item) {
return i;
}
i++;
lastItem = item;
}
return -1;
return { invalidNodes: invalidNodes };
}
//# sourceMappingURL=noMixedInterfaceRule.js.map
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var ts = require("typescript");
var Lint = require("tslint");
var OPTION_IGNORE_PREFIX = "ignore-prefix";
function parseOptions(options) {
var ignorePrefix;
for (var _i = 0, options_1 = options; _i < options_1.length; _i++) {
var o = options_1[_i];
if (typeof o === "object" && o[OPTION_IGNORE_PREFIX] !== null) {
ignorePrefix = o[OPTION_IGNORE_PREFIX];
break;
}
}
return { ignorePrefix: ignorePrefix };
}
var Rule = (function (_super) {
__extends(Rule, _super);
function Rule() {
return _super !== null && _super.apply(this, arguments) || this;
}
Rule.prototype.apply = function (sourceFile) {
var noObjectMutationWalker = new NoObjectMutationWalker(sourceFile, this.getOptions());
return this.applyWithWalker(noObjectMutationWalker);
};
return Rule;
}(Lint.Rules.AbstractRule));
Rule.FAILURE_STRING = "Modifying properties of existing object not allowed.";
exports.Rule = Rule;
var check_node_1 = require("./shared/check-node");
var Ignore = require("./shared/ignore");
// tslint:disable-next-line:variable-name
exports.Rule = check_node_1.createCheckNodeRule(checkNode, "Modifying properties of existing object not allowed.");
var objPropAccessors = [

@@ -63,65 +31,41 @@ ts.SyntaxKind.ElementAccessExpression,

];
var NoObjectMutationWalker = (function (_super) {
__extends(NoObjectMutationWalker, _super);
function NoObjectMutationWalker(sourceFile, options) {
var _this = _super.call(this, sourceFile, options) || this;
Object.assign(_this, parseOptions(options.ruleArguments));
return _this;
function checkNode(node, ctx) {
var invalidNodes = [];
// No assignment with object.property on the left
if (node && node.kind === ts.SyntaxKind.BinaryExpression) {
var binExp_1 = node;
if (objPropAccessors.some(function (k) { return k === binExp_1.left.kind; }) &&
forbidObjPropOnLeftSideOf.some(function (k) { return k === binExp_1.operatorToken.kind; }) &&
!Ignore.isIgnoredPrefix(binExp_1.getText(node.getSourceFile()), ctx.options.ignorePrefix)) {
invalidNodes = invalidNodes.concat([check_node_1.createInvalidNode(node)]);
}
}
NoObjectMutationWalker.prototype.visitNode = function (node) {
// No assignment with object.property on the left
if (node && node.kind === ts.SyntaxKind.BinaryExpression) {
var binExp_1 = node;
if (objPropAccessors.some(function (k) { return k === binExp_1.left.kind; }) &&
forbidObjPropOnLeftSideOf.some(function (k) { return k === binExp_1.operatorToken.kind; }) &&
!this.isIgnored(binExp_1.getText(this.getSourceFile()))) {
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), Rule.FAILURE_STRING));
}
// No deleting object properties
if (node && node.kind === ts.SyntaxKind.DeleteExpression) {
var delExp_1 = node;
if (objPropAccessors.some(function (k) { return k === delExp_1.expression.kind; }) &&
!Ignore.isIgnoredPrefix(delExp_1.expression.getText(node.getSourceFile()), ctx.options.ignorePrefix)) {
invalidNodes = invalidNodes.concat([check_node_1.createInvalidNode(node)]);
}
// No deleting object properties
if (node && node.kind === ts.SyntaxKind.DeleteExpression) {
var delExp_1 = node;
if (objPropAccessors.some(function (k) { return k === delExp_1.expression.kind; }) &&
!this.isIgnored(delExp_1.expression.getText(this.getSourceFile()))) {
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), Rule.FAILURE_STRING));
}
}
// No prefix inc/dec
if (node && node.kind === ts.SyntaxKind.PrefixUnaryExpression) {
var preExp_1 = node;
if (objPropAccessors.some(function (k) { return k === preExp_1.operand.kind; }) &&
forbidUnaryOps.some(function (o) { return o === preExp_1.operator; }) &&
!Ignore.isIgnoredPrefix(preExp_1.operand.getText(node.getSourceFile()), ctx.options.ignorePrefix)) {
invalidNodes = invalidNodes.concat([check_node_1.createInvalidNode(node)]);
}
// No prefix inc/dec
if (node && node.kind === ts.SyntaxKind.PrefixUnaryExpression) {
var preExp_1 = node;
if (objPropAccessors.some(function (k) { return k === preExp_1.operand.kind; }) &&
forbidUnaryOps.some(function (o) { return o === preExp_1.operator; }) &&
!this.isIgnored(preExp_1.operand.getText(this.getSourceFile()))) {
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), Rule.FAILURE_STRING));
}
}
// No postfix inc/dec
if (node && node.kind === ts.SyntaxKind.PostfixUnaryExpression) {
var postExp_1 = node;
if (objPropAccessors.some(function (k) { return k === postExp_1.operand.kind; }) &&
forbidUnaryOps.some(function (o) { return o === postExp_1.operator; }) &&
!Ignore.isIgnoredPrefix(postExp_1.getText(node.getSourceFile()), ctx.options.ignorePrefix)) {
invalidNodes = invalidNodes.concat([check_node_1.createInvalidNode(node)]);
}
// No postfix inc/dec
if (node && node.kind === ts.SyntaxKind.PostfixUnaryExpression) {
var postExp_1 = node;
if (objPropAccessors.some(function (k) { return k === postExp_1.operand.kind; }) &&
forbidUnaryOps.some(function (o) { return o === postExp_1.operator; }) &&
!this.isIgnored(postExp_1.getText(this.getSourceFile()))) {
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), Rule.FAILURE_STRING));
}
}
_super.prototype.visitNode.call(this, node);
};
NoObjectMutationWalker.prototype.isIgnored = function (text) {
if (!this.ignorePrefix) {
return false;
}
if (Array.isArray(this.ignorePrefix)) {
if (this.ignorePrefix.find(function (pfx) { return text.indexOf(pfx) === 0; })) {
return true;
}
}
else {
if (text.indexOf(this.ignorePrefix) === 0) {
return true;
}
}
return false;
};
return NoObjectMutationWalker;
}(Lint.RuleWalker));
}
return { invalidNodes: invalidNodes };
}
//# sourceMappingURL=noObjectMutationRule.js.map
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var ts = require("typescript");
var Lint = require("tslint");
var Rule = (function (_super) {
__extends(Rule, _super);
function Rule() {
return _super !== null && _super.apply(this, arguments) || this;
}
Rule.prototype.apply = function (sourceFile) {
var noThisKeywordWalker = new NoThisWalker(sourceFile, this.getOptions());
return this.applyWithWalker(noThisKeywordWalker);
};
return Rule;
}(Lint.Rules.AbstractRule));
Rule.FAILURE_STRING = "Unexpected this, use functions not classes.";
exports.Rule = Rule;
var NoThisWalker = (function (_super) {
__extends(NoThisWalker, _super);
function NoThisWalker() {
return _super !== null && _super.apply(this, arguments) || this;
}
NoThisWalker.prototype.visitNode = function (node) {
if (node && node.kind === ts.SyntaxKind.ThisKeyword) {
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), Rule.FAILURE_STRING));
}
_super.prototype.visitNode.call(this, node);
};
return NoThisWalker;
}(Lint.RuleWalker));
var check_node_1 = require("./shared/check-node");
// tslint:disable-next-line:variable-name
exports.Rule = check_node_1.createCheckNodeRule(checkNode, "Unexpected this, use functions not classes.");
function checkNode(node, _ctx) {
return node && node.kind === ts.SyntaxKind.ThisKeyword
? { invalidNodes: [check_node_1.createInvalidNode(node)] }
: {
invalidNodes: []
};
}
//# sourceMappingURL=noThisRule.js.map
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var ts = require("typescript");
var Lint = require("tslint");
var Shared = require("./readonly-shared");
var Rule = (function (_super) {
__extends(Rule, _super);
function Rule() {
return _super !== null && _super.apply(this, arguments) || this;
}
Rule.prototype.apply = function (sourceFile) {
return this.applyWithFunction(sourceFile, function (ctx) { return Shared.walk(ctx, checkNode, "Only ReadonlyArray allowed."); }, Shared.parseOptions(this.ruleArguments));
};
return Rule;
}(Lint.Rules.AbstractRule));
exports.Rule = Rule;
var Ignore = require("./shared/ignore");
var check_node_1 = require("./shared/check-node");
// tslint:disable-next-line:variable-name
exports.Rule = check_node_1.createCheckNodeRule(Ignore.checkNodeWithIgnore(checkNode), "Only ReadonlyArray allowed.");
function checkNode(node, ctx) {
var explicitTypeFailures = checkArrayTypeOrReference(node, ctx);
var implicitTypeFailures = checkVariableOrParameterImplicitType(node, ctx);
return explicitTypeFailures.concat(implicitTypeFailures);
return { invalidNodes: explicitTypeFailures.concat(implicitTypeFailures) };
}
function checkArrayTypeOrReference(node, ctx) {
// We need to check both shorthand syntax "number[]" and type reference "Array<number>"
if (node.kind === ts.SyntaxKind.ArrayType
|| (node.kind === ts.SyntaxKind.TypeReference && node.typeName.getText(ctx.sourceFile) === "Array")) {
if (node.parent && Shared.shouldIgnorePrefix(node.parent, ctx.options, ctx.sourceFile)) {
if (node.kind === ts.SyntaxKind.ArrayType ||
(node.kind === ts.SyntaxKind.TypeReference &&
node.typeName.getText(ctx.sourceFile) ===
"Array")) {
if (node.parent &&
Ignore.shouldIgnorePrefix(node.parent, ctx.options, ctx.sourceFile)) {
return [];

@@ -47,7 +32,11 @@ }

if (typeNode.typeArguments) {
typeArgument = typeNode.typeArguments[0].getFullText(ctx.sourceFile).trim();
typeArgument = typeNode.typeArguments[0]
.getFullText(ctx.sourceFile)
.trim();
}
}
var length_1 = node.getWidth(ctx.sourceFile);
return [Shared.createInvalidNode(node, new Lint.Replacement(node.end - length_1, length_1, "ReadonlyArray<" + typeArgument + ">"))];
return [
check_node_1.createInvalidNode(node, new Lint.Replacement(node.end - length_1, length_1, "ReadonlyArray<" + typeArgument + ">"))
];
}

@@ -57,11 +46,13 @@ return [];

function checkVariableOrParameterImplicitType(node, ctx) {
if (node.kind === ts.SyntaxKind.VariableDeclaration || node.kind === ts.SyntaxKind.Parameter
|| node.kind === ts.SyntaxKind.PropertyDeclaration) {
if (node.kind === ts.SyntaxKind.VariableDeclaration ||
node.kind === ts.SyntaxKind.Parameter ||
node.kind === ts.SyntaxKind.PropertyDeclaration) {
// The initializer is used to set and implicit type
var varOrParamNode = node;
if (Shared.shouldIgnorePrefix(node, ctx.options, ctx.sourceFile)) {
if (Ignore.shouldIgnorePrefix(node, ctx.options, ctx.sourceFile)) {
return [];
}
if (!varOrParamNode.type) {
if (varOrParamNode.initializer && varOrParamNode.initializer.kind === ts.SyntaxKind.ArrayLiteralExpression) {
if (varOrParamNode.initializer &&
varOrParamNode.initializer.kind === ts.SyntaxKind.ArrayLiteralExpression) {
var length_2 = varOrParamNode.name.getWidth(ctx.sourceFile);

@@ -82,3 +73,5 @@ var nameText = varOrParamNode.name.getText(ctx.sourceFile);

// }
return [Shared.createInvalidNode(varOrParamNode.name, new Lint.Replacement(varOrParamNode.name.end - length_2, length_2, nameText + ": ReadonlyArray<" + typeArgument + ">"))];
return [
check_node_1.createInvalidNode(varOrParamNode.name, new Lint.Replacement(varOrParamNode.name.end - length_2, length_2, nameText + ": ReadonlyArray<" + typeArgument + ">"))
];
}

@@ -85,0 +78,0 @@ }

"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var ts = require("typescript");
var Lint = require("tslint");
var Shared = require("./readonly-shared");
var Ignore = require("./shared/ignore");
var check_node_1 = require("./shared/check-node");
/**

@@ -20,17 +11,6 @@ * This rule checks that the readonly keyword is used in all PropertySignature and

*/
var Rule = (function (_super) {
__extends(Rule, _super);
function Rule() {
return _super !== null && _super.apply(this, arguments) || this;
}
Rule.prototype.apply = function (sourceFile) {
return this.applyWithFunction(sourceFile, function (ctx) {
return Shared.walk(ctx, checkNode, "A readonly modifier is required.");
}, Shared.parseOptions(this.ruleArguments));
};
return Rule;
}(Lint.Rules.AbstractRule));
exports.Rule = Rule;
// tslint:disable-next-line:variable-name
exports.Rule = check_node_1.createCheckNodeRule(Ignore.checkNodeWithIgnore(checkNode), "A readonly modifier is required.");
function checkNode(node, ctx) {
return checkPropertySignatureAndIndexSignature(node, ctx);
return { invalidNodes: checkPropertySignatureAndIndexSignature(node, ctx) };
}

@@ -45,3 +25,3 @@ function checkPropertySignatureAndIndexSignature(node, ctx) {

// Check if ignore-prefix applies
if (Shared.shouldIgnorePrefix(node, ctx.options, ctx.sourceFile)) {
if (Ignore.shouldIgnorePrefix(node, ctx.options, ctx.sourceFile)) {
return [];

@@ -53,3 +33,3 @@ }

return [
Shared.createInvalidNode(node, new Lint.Replacement(node.end - length_1, length_1, "readonly " + fulltext))
check_node_1.createInvalidNode(node, new Lint.Replacement(node.end - length_1, length_1, "readonly " + fulltext))
];

@@ -56,0 +36,0 @@ }

{
"rulesDirectory": "./rules",
"rules": {
"readonly-keyword": false,
"readonly-array": false,
"no-class": false,
"no-delete": false,
"no-expression-statement": false,
"no-if-statement": false,
"no-let": false,
"no-loop-statement": false,
"no-method-signature": false,
"no-mixed-interface": false,
"no-object-mutation": false,
"no-this": false,
"no-class": false,
"no-mixed-interface": false,
"no-expression-statement": false,
"no-object-mutation": false
"readonly-keyword": false,
"readonly-array": false
}
}
{
"rulesDirectory": ["tslint-plugin-prettier"],
"rules": {
"prettier": true,
"no-any": true,

@@ -83,3 +85,3 @@ "no-internal-module": true,

"semicolon": [true, "always", "ignore-interfaces"],
"variable-name": [true, "ban-keywords", "check-format"],
"variable-name": [true, "ban-keywords", "check-format", "allow-leading-underscore"],
"whitespace": [

@@ -86,0 +88,0 @@ true,

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc