Skip to content
This repository has been archived by the owner on Mar 25, 2021. It is now read-only.

strict-type-predicates: allow comparing typeof with expression #3542

Merged
merged 2 commits into from
Jan 9, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions src/rules/strictTypePredicatesRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
* limitations under the License.
*/

import { isBinaryExpression, isTypeFlagSet, isUnionType } from "tsutils";
import { isBinaryExpression, isIdentifier, isLiteralExpression, isTypeFlagSet, isUnionType } from "tsutils";

import * as ts from "typescript";
import { showWarningOnce } from "../error";
Expand Down Expand Up @@ -130,11 +130,19 @@ function getTypePredicateOneWay(left: ts.Expression, right: ts.Expression, isStr
switch (right.kind) {
case ts.SyntaxKind.TypeOfExpression:
const expression = (right as ts.TypeOfExpression).expression;
const kind = left.kind === ts.SyntaxKind.StringLiteral ? (left as ts.StringLiteral).text : "";
const predicate = getTypePredicateForKind(kind);
if (!isLiteralExpression(left)) {
if (isIdentifier(left) && left.text === "undefined" ||
left.kind === ts.SyntaxKind.NullKeyword ||
left.kind === ts.SyntaxKind.TrueKeyword ||
left.kind === ts.SyntaxKind.FalseKeyword) {
return {kind: TypePredicateKind.TypeofTypo};
}
return undefined;
}
const predicate = getTypePredicateForKind(left.text);
return predicate === undefined
? { kind: TypePredicateKind.TypeofTypo }
: { kind: TypePredicateKind.Plain, expression, predicate, isNullOrUndefined: kind === "undefined" };
: { kind: TypePredicateKind.Plain, expression, predicate, isNullOrUndefined: left.text === "undefined" };

case ts.SyntaxKind.NullKeyword:
return nullOrUndefined(ts.TypeFlags.Null);
Expand Down
16 changes: 16 additions & 0 deletions test/rules/strict-type-predicates/strict-null-checks/test.ts.lint
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,22 @@ declare function get<T>(): T;

typeof get<any>() === "orbject";
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [typeof]

typeof get<string | number>() === `string`;
typeof get<string | number>() === `stirng`;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [typeof]

let a: string, b: string;
typeof a === typeof b;
typeof a === b;
a === typeof b;
typeof a === undefined;
~~~~~~~~~~~~~~~~~~~~~~ [F]

undefined === typeof a;
~~~~~~~~~~~~~~~~~~~~~~ [typeof]
null === typeof b;
~~~~~~~~~~~~~~~~~ [typeof]
}

[T]: Expression is always true.
Expand Down