Skip to content

Commit

Permalink
no-redundant-undefined: enforce undefined for optional parameters (#…
Browse files Browse the repository at this point in the history
…335)

* make optional properties require undefined

* rename to redundant-undefined

* add missed no-redundant-undefined references

* add fix for missing undefined

* improve fix to handle function types

* Remove checks on properties

Including undefined, or not, is now semantically meaningful when
exactOptionalPropertyTypes is true.
  • Loading branch information
sandersn committed Nov 29, 2021
1 parent 6286276 commit 74d23be
Show file tree
Hide file tree
Showing 8 changed files with 67 additions and 89 deletions.
31 changes: 0 additions & 31 deletions packages/dtslint/docs/no-redundant-undefined.md

This file was deleted.

15 changes: 15 additions & 0 deletions packages/dtslint/docs/redundant-undefined.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# redundant-undefined

Avoid explicitly specifying `undefined` as a type for a parameter which is already optional.

**Bad**:

```ts
function f(s?: string | undefined): void {}
```

**Good**:

```ts
function f(s?: string): void {}
```
1 change: 1 addition & 0 deletions packages/dtslint/dtslint.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"no-dead-reference": true,
"no-import-default-of-export-equals": true,
"no-padding": true,
"redundant-undefined": true,
"no-relative-import-in-test": true,
"strict-export-declare-modifiers": true,
"no-any-union": true,
Expand Down
48 changes: 0 additions & 48 deletions packages/dtslint/src/rules/noRedundantUndefinedRule.ts

This file was deleted.

40 changes: 40 additions & 0 deletions packages/dtslint/src/rules/redundantUndefinedRule.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import * as Lint from "tslint";
import * as ts from "typescript";

import { failure } from "../util";

export class Rule extends Lint.Rules.AbstractRule {
static metadata: Lint.IRuleMetadata = {
ruleName: "redundant-undefined",
description: "Forbids optional parameters to include an explicit `undefined` in their type; requires it in optional properties.",
optionsDescription: "Not configurable.",
options: null,
type: "style",
typescriptOnly: true,
};

apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
return this.applyWithFunction(sourceFile, walk);
}
}

function walk(ctx: Lint.WalkContext<void>): void {
if (ctx.sourceFile.fileName.includes('node_modules')) return;
ctx.sourceFile.forEachChild(function recur(node) {
if (node.kind === ts.SyntaxKind.UndefinedKeyword
&& ts.isUnionTypeNode(node.parent!)
&& isOptionalParameter(node.parent!.parent!)) {
ctx.addFailureAtNode(
node,
failure(
Rule.metadata.ruleName,
`Parameter is optional, so no need to include \`undefined\` in the type.`));
}
node.forEachChild(recur);
});
}

function isOptionalParameter(node: ts.Node): boolean {
return node.kind === ts.SyntaxKind.Parameter
&& (node as ts.ParameterDeclaration).questionToken !== undefined;
}
9 changes: 0 additions & 9 deletions packages/dtslint/test/no-redundant-undefined/test.ts.lint

This file was deleted.

10 changes: 10 additions & 0 deletions packages/dtslint/test/redundant-undefined/test.ts.lint
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
function f(s?: string | undefined): void {}
~~~~~~~~~ [0]

interface I {
ok?: string | undefined;
s?: string;
almost?: number | string;
}

[0]: Parameter is optional, so no need to include `undefined` in the type. See: https://github.com/Microsoft/dtslint/blob/master/docs/redundant-undefined.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"rulesDirectory": ["../../bin/rules"],
"rules": {
"no-redundant-undefined": true
"redundant-undefined": true
}
}

0 comments on commit 74d23be

Please sign in to comment.