Skip to content

Commit

Permalink
WIP: Port docs for each rule (#3)
Browse files Browse the repository at this point in the history
* some work on readonly-keyword

* readonly

* Spelling

* Format

* Casing

* readonly array

* no-let

* no-array-mutation

* no-object-mutation

* no-method-signature

* no-delete

* no-class

* no-mixed-interface

* no-expression-statement

* no-if-statement

* no-loop-statement

* no-throw

* no-try

* no-reject
  • Loading branch information
jonaskello authored Jul 2, 2019
1 parent 3f04042 commit c19b92e
Show file tree
Hide file tree
Showing 20 changed files with 296 additions and 180 deletions.
40 changes: 20 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,29 +77,29 @@ In addition to immutable rules this project also contains a few rules for enforc

### Immutability rules

| Name | Description | :heavy_check_mark: | :wrench: | :thought_balloon: |
| ------------------------------------------------------------------------- | -------------------------------------------------------------------------- | ------------------ | -------- | ----------------- |
| [`ts-immutable/readonly-keyword`](./docs/rules/readonly-keyword.md) | Enforce readonly modifiers are used where possible. | :heavy_check_mark: | :wrench: | |
| [`ts-immutable/readonly-array`](./docs/rules/readonly-array.md) | Prefer readonly array over mutable arrays. | :heavy_check_mark: | :wrench: | |
| [`ts-immutable/no-let`](./docs/rules/no-let.md) | Disallow mutable variables. | :heavy_check_mark: | :wrench: | |
| [`ts-immutable/no-array-mutation`](./docs/rules/no-array-mutation.md) | Disallow mutating arrays. | :heavy_check_mark: | | :thought_balloon: |
| [`ts-immutable/no-object-mutation`](./docs/rules/no-object-mutation.md) | WIP | :heavy_check_mark: | | :thought_balloon: |
| [`ts-immutable/no-method-signature`](./docs/rules/no-method-signature.md) | Prefer property signatures with readonly modifiers over method signatures. | :heavy_check_mark: | | |
| [`ts-immutable/no-delete`](./docs/rules/no-delete.md) | Disallow delete expressions. | :heavy_check_mark: | | |
| Name | Description | :heavy_check_mark: | :wrench: | :thought_balloon: |
| ------------------------------------------------------------------------- | ------------------------------------------------------------------------- | ------------------ | -------- | ----------------- |
| [`ts-immutable/readonly-keyword`](./docs/rules/readonly-keyword.md) | Enforce readonly modifiers are used where possible | :heavy_check_mark: | :wrench: | |
| [`ts-immutable/readonly-array`](./docs/rules/readonly-array.md) | Prefer readonly array over mutable arrays | :heavy_check_mark: | :wrench: | |
| [`ts-immutable/no-let`](./docs/rules/no-let.md) | Disallow mutable variables | :heavy_check_mark: | :wrench: | |
| [`ts-immutable/no-array-mutation`](./docs/rules/no-array-mutation.md) | Disallow mutating arrays | :heavy_check_mark: | | :thought_balloon: |
| [`ts-immutable/no-object-mutation`](./docs/rules/no-object-mutation.md) | Disallow mutating objects | :heavy_check_mark: | | :thought_balloon: |
| [`ts-immutable/no-method-signature`](./docs/rules/no-method-signature.md) | Prefer property signatures with readonly modifiers over method signatures | :heavy_check_mark: | | |
| [`ts-immutable/no-delete`](./docs/rules/no-delete.md) | Disallow delete expressions | :heavy_check_mark: | | |

### Functional style rules

| Name | Description | :heavy_check_mark: | :wrench: | :thought_balloon: |
| --------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- | ------------------ | -------- | ----------------- |
| [`ts-immutable/no-this`](./docs/rules/no-this.md) | Disallow this access. | :heavy_check_mark: | | |
| [`ts-immutable/no-class`](./docs/rules/no-class.md) | Disallow classes. | :heavy_check_mark: | | |
| [`ts-immutable/no-mixed-interface`](./docs/rules/no-mixed-interface.md) | Restrict interfaces so that only members of the same kind of are allowed in them. | :heavy_check_mark: | | |
| [`ts-immutable/no-expression-statement`](./docs/rules/no-expression-statement.md) | Using expressions to cause side-effects not allowed. | :heavy_check_mark: | | |
| [`ts-immutable/no-if-statement`](./docs/rules/no-if-statement.md) | Disallow if statements. | :heavy_check_mark: | | |
| [`ts-immutable/no-loop-statement`](./docs/rules/no-loop-statement.md) | Disallow imperative loops. | :heavy_check_mark: | | |
| [`ts-immutable/no-throw`](./docs/rules/no-throw.md) | Disallow throwing exceptions. | :heavy_check_mark: | | |
| [`ts-immutable/no-try`](./docs/rules/no-try.md) | Disallow try-catch[-finally] and try-finally patterns. | :heavy_check_mark: | | |
| [`ts-immutable/no-reject`](./docs/rules/no-reject.md) | Disallow try-catch[-finally] and try-finally patterns. | :heavy_check_mark: | | |
| Name | Description | :heavy_check_mark: | :wrench: | :thought_balloon: |
| --------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | ------------------ | -------- | ----------------- |
| [`ts-immutable/no-this`](./docs/rules/no-this.md) | Disallow this access | :heavy_check_mark: | | |
| [`ts-immutable/no-class`](./docs/rules/no-class.md) | Disallow classes | :heavy_check_mark: | | |
| [`ts-immutable/no-mixed-interface`](./docs/rules/no-mixed-interface.md) | Restrict interfaces so that only members of the same kind of are allowed in them | :heavy_check_mark: | | |
| [`ts-immutable/no-expression-statement`](./docs/rules/no-expression-statement.md) | Using expressions to cause side-effects not allowed | :heavy_check_mark: | | |
| [`ts-immutable/no-if-statement`](./docs/rules/no-if-statement.md) | Disallow if statements | :heavy_check_mark: | | |
| [`ts-immutable/no-loop-statement`](./docs/rules/no-loop-statement.md) | Disallow imperative loops | :heavy_check_mark: | | |
| [`ts-immutable/no-throw`](./docs/rules/no-throw.md) | Disallow throwing exceptions | :heavy_check_mark: | | |
| [`ts-immutable/no-try`](./docs/rules/no-try.md) | Disallow try-catch[-finally] and try-finally patterns | :heavy_check_mark: | | |
| [`ts-immutable/no-reject`](./docs/rules/no-reject.md) | Disallow try-catch[-finally] and try-finally patterns | :heavy_check_mark: | | |

## Recommended standard rules

Expand Down
46 changes: 26 additions & 20 deletions docs/rules/no-array-mutation.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
### no-array-mutation
# Disallow mutating arrays (no-array-mutation)

[![Type Info Required][type-info-badge]][type-info-url]
This rule prohibits mutating an array via assignment to or deletion of their elements/properties. This rule enforces array immutability without the use of `ReadonlyArray<T>` (as apposed to [readonly-array](./readonly-array.md)).

This rule prohibits mutating an array via assignment to or deletion of their elements/properties. This rule enforces array immutability without the use of `ReadonlyArray<T>` (as apposed to [readonly-array](#readonly-array)).
## Rule Details

```typescript
const x = [0, 1, 2];
Expand All @@ -12,28 +12,34 @@ x.length = 1; // <- Mutating an array is not allowed.
x.push(3); // <- Mutating an array is not allowed.
```

#### Has Fixer
## Options

No
The rule accepts an options object with the following properties:

#### Options
```typescript
type Options = {
readonly ignoreNewArray?: boolean;
readonly ignorePattern?: string | Array<string>;
readonly ignorePrefix?: string | Array<string>;
readonly ignoreSuffix?: string | Array<string>;
};

const defaults = {
ignoreNewArray: false
};
```

- [ignore-prefix](#using-the-ignore-prefix-option)
- [ignore-suffix](#using-the-ignore-suffix-option)
- [ignore-pattern](#using-the-ignore-pattern-option)
- [ignore-new-array](#using-the-ignore-new-array-option-with-no-array-mutation)
- ~~ignore-mutation-following-accessor~~ - _deprecated in favor of [ignore-new-array](#using-the-ignore-new-array-option-with-no-array-mutation)_
### `ignore-new-array`

#### Example config
This option allows for the use of array mutator methods to be chained to newly created arrays.

```javascript
"no-array-mutation": true
```
For example, an array can be immutably sorted like so:

```javascript
"no-array-mutation": [true, {"ignore-prefix": "mutable"}]
```typescript
const original = ["foo", "bar", "baz"];
const sorted = original.slice().sort((a, b) => a.localeCompare(b)); // This is OK with ignore-new-array - note the use of the `slice` method which returns a copy of the original array.
```

```javascript
"no-array-mutation": [true, "ignore-new-array"]
```
### `ignorePattern`

See the [ignorePattern](./options-ignore-pattern.md) docs.
10 changes: 9 additions & 1 deletion docs/rules/no-class.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
### no-class
# Disallow classes (no-class)

Disallow use of the `class` keyword.

## Rule Details

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.

Expand Down Expand Up @@ -30,3 +34,7 @@ const OptimizedMessage = pure(Message);
// Even more optimized: only updates if specific prop keys have changed
const HyperOptimizedMessage = onlyUpdateForKeys(["message"], Message);
```

## Options

The rule does not accept any options.
8 changes: 7 additions & 1 deletion docs/rules/no-delete.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
### no-delete
# Disallow delete expressions (no-delete)

The delete operator allows for mutating objects by deleting keys. This rule disallows any delete expressions.

## Rule Details

```typescript
delete object.property; // Unexpected delete, objects should be considered immutable.
```
Expand All @@ -11,3 +13,7 @@ As an alternative the spread operator can be used to delete a key in an object (
```typescript
const { [action.id]: deletedItem, ...rest } = state;
```

## Options

The rule does not accept any options.
30 changes: 16 additions & 14 deletions docs/rules/no-expression-statement.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
### no-expression-statement
# Using expressions to cause side-effects not allowed (no-expression-statement)

This rule checks that the value of an expression is assigned to a variable and thus helps promote side-effect free (pure) functions.

## Rule Details

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.

Expand All @@ -7,22 +11,20 @@ array.push(1);
alert("Hello world!");
```

This rule checks that the value of an expression is assigned to a variable and thus helps promote side-effect free (pure) functions.

#### Options
## Options

- [ignore-prefix](#using-the-ignore-prefix-option-with-no-expression-statement)
The rule accepts an options object with the following properties:

#### Example config
```typescript
type Options = {
readonly ignorePattern?: string | Array<string>;
readonly ignorePrefix?: string | Array<string>;
readonly ignoreSuffix?: string | Array<string>;
};

```javascript
"no-expression-statement": true
const defaults = {};
```

```javascript
"no-expression-statement": [true, {"ignore-prefix": "console."}]
```
### `ignorePattern`

```javascript
"no-expression-statement": [true, {"ignore-prefix": ["console.log", "console.error"]}]
```
See the [ignorePattern](./options-ignore-pattern.md) docs.
12 changes: 10 additions & 2 deletions docs/rules/no-if-statement.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
### no-if-statement
# Disallow if statements (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.
This rule disallows if statements.

## Rule Details

If statements is not a good fit for functional style programming as they are not expresssions and do not return a value.

```typescript
let x;
Expand All @@ -18,3 +22,7 @@ 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).

## Options

The rule does not accept any options.
40 changes: 21 additions & 19 deletions docs/rules/no-let.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
### no-let
# Disallow mutable variables (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`.

## Rule Details

There's no reason to use `let` in a Redux/React application, because all your state is managed by either Redux or React. Use `const` instead, and avoid state bugs altogether.

```typescript
Expand All @@ -21,27 +23,27 @@ const SearchResults = ({ results }) => (
);
```

#### Has Fixer
## Options

Yes
The rule accepts an options object with the following properties:

#### Options
```typescript
type Options = {
readonly ignoreLocal?: boolean;
readonly ignorePattern?: string | Array<string>;
readonly ignorePrefix?: string | Array<string>;
readonly ignoreSuffix?: string | Array<string>;
};

const defaults = {
ignoreLocal: false
};
```

- [ignore-local](#using-the-ignore-local-option)
- [ignore-prefix](#using-the-ignore-prefix-option)
- [ignore-suffix](#using-the-ignore-suffix-option)
- [ignore-pattern](#using-the-ignore-pattern-option)
### `ignoreLocal`

#### Example config
See the [ignoreLocal](./options-ignore-local.md) docs.

```javascript
"no-let": true
```
### `ignorePattern`

```javascript
"no-let": [true, "ignore-local"]
```

```javascript
"no-let": [true, "ignore-local", {"ignore-prefix": "mutable"}]
```
See the [ignorePattern](./options-ignore-pattern.md) docs.
12 changes: 10 additions & 2 deletions docs/rules/no-loop-statement.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
### no-loop-statement
# Disallow imperative loops (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`.
This rule disallows for loop statements, including `for`, `for...of`, `for...in`, `while`, and `do...while`.

## Rule Details

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.

```typescript
const numbers = [1, 2, 3];
Expand All @@ -18,3 +22,7 @@ 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

The rule does not accept any options.
10 changes: 9 additions & 1 deletion docs/rules/no-method-signature.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
### no-method-signature
# Prefer property signatures with readonly modifiers over method signatures (no-method-signature)

Prefer property signatures with readonly modifiers over method signatures.

## Rule Details

There are two ways function members can be declared in an interface or type alias:

Expand All @@ -10,3 +14,7 @@ interface Zoo {
```

The `MethodSignature` and the `PropertySignature` forms seem equivalent, but only the `PropertySignature` form can have a `readonly` modifier. Becuase of this any `MethodSignature` will be mutable. Therefore the `no-method-signature` rule disallows usage of this form and instead proposes to use the `PropertySignature` which can have a `readonly` modifier. It should be noted however that the `PropertySignature` form for declaring functions does not support overloading.

## Options

The rule does not accept any options.
12 changes: 10 additions & 2 deletions docs/rules/no-mixed-interface.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
### no-mixed-interface
# Restrict interfaces so that only members of the same kind of are allowed in them (no-mixed-interface)

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.
This rule enforces that an inteface only has one type of members, eg. only data properties or only functions.

## Rule Details

Mixing functions and data properties in the same interface is a sign of object-orientation style.

## Options

The rule does not accept any options.
Loading

0 comments on commit c19b92e

Please sign in to comment.