Skip to content

Commit

Permalink
Refine no-unnecessary-type-assertion rule to not flag necessary asser…
Browse files Browse the repository at this point in the history
…tions (palantir#3120)

* Refine no-unnecessary-type-assertion rule to not flag necessary assertions

Type assertions prevent a type from being widened in a couple of
situations, such as in an object literal or the inferred return type of
a function.

* Fix lint errors.

* Use isObjectType to avoid cast
  • Loading branch information
calebegg authored and HyphnKnight committed Apr 9, 2018
1 parent 68c167d commit 12dface
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 0 deletions.
10 changes: 10 additions & 0 deletions src/rules/noUnnecessaryTypeAssertionRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
* limitations under the License.
*/

import { isObjectFlagSet, isObjectType, isTypeFlagSet } from "tsutils";
import * as ts from "typescript";
import * as Lint from "../index";

Expand Down Expand Up @@ -65,6 +66,15 @@ class Walker extends Lint.AbstractWalker<void> {
return;
}

if (node.kind !== ts.SyntaxKind.NonNullExpression &&
(isTypeFlagSet(castType, ts.TypeFlags.Literal) ||
isObjectType(castType) &&
isObjectFlagSet(castType, ts.ObjectFlags.Tuple))) {
// It's not always safe to remove a cast to a literal type or tuple
// type, as those types are sometimes widened without the cast.
return;
}

const uncastType = this.checker.getTypeAtLocation(node.expression);
if (uncastType === castType) {
this.addFailureAtNode(node, Rule.FAILURE_STRING, node.kind === ts.SyntaxKind.TypeAssertionExpression
Expand Down
10 changes: 10 additions & 0 deletions test/rules/no-unnecessary-type-assertion/test.ts.fix
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,13 @@ function func(aOrB: TypeA|TypeB) {
let z = aOrB;
}
}

// Expecting no warning for these assertions as they are not unnecessary.

type Bar = 'bar';
const data = {
x: 'foo' as 'foo',
y: 'bar' as Bar,
}

[1, 2, 3, 4, 5].map(x => [x, 'A' + x] as [number, string]);
10 changes: 10 additions & 0 deletions test/rules/no-unnecessary-type-assertion/test.ts.lint
Original file line number Diff line number Diff line change
Expand Up @@ -86,3 +86,13 @@ function func(aOrB: TypeA|TypeB) {
~~~~~~~~~~~ [This assertion is unnecessary since it does not change the type of the expression.]
}
}

// Expecting no warning for these assertions as they are not unnecessary.

type Bar = 'bar';
const data = {
x: 'foo' as 'foo',
y: 'bar' as Bar,
}

[1, 2, 3, 4, 5].map(x => [x, 'A' + x] as [number, string]);

0 comments on commit 12dface

Please sign in to comment.