mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-06 02:33:53 -06:00
Improve uncalled function check related to parenthesized and binary expressions (#50756)
fixes https://github.com/microsoft/TypeScript/issues/37598
This commit is contained in:
parent
f6fc444b33
commit
16c695cdbb
@ -172,7 +172,10 @@ import {
|
||||
isJSDocTypeAlias,
|
||||
isJsonSourceFile,
|
||||
isLeftHandSideExpression,
|
||||
isLogicalOrCoalescingAssignmentExpression,
|
||||
isLogicalOrCoalescingAssignmentOperator,
|
||||
isLogicalOrCoalescingBinaryExpression,
|
||||
isLogicalOrCoalescingBinaryOperator,
|
||||
isModuleAugmentationExternal,
|
||||
isModuleBlock,
|
||||
isModuleDeclaration,
|
||||
@ -1377,17 +1380,13 @@ function createBinder(): (file: SourceFile, options: CompilerOptions) => void {
|
||||
node = (node as PrefixUnaryExpression).operand;
|
||||
}
|
||||
else {
|
||||
return node.kind === SyntaxKind.BinaryExpression && (
|
||||
(node as BinaryExpression).operatorToken.kind === SyntaxKind.AmpersandAmpersandToken ||
|
||||
(node as BinaryExpression).operatorToken.kind === SyntaxKind.BarBarToken ||
|
||||
(node as BinaryExpression).operatorToken.kind === SyntaxKind.QuestionQuestionToken);
|
||||
return isLogicalOrCoalescingBinaryExpression(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function isLogicalAssignmentExpression(node: Node) {
|
||||
node = skipParentheses(node);
|
||||
return isBinaryExpression(node) && isLogicalOrCoalescingAssignmentOperator(node.operatorToken.kind);
|
||||
return isLogicalOrCoalescingAssignmentExpression(skipParentheses(node));
|
||||
}
|
||||
|
||||
function isTopLevelLogicalExpression(node: Node): boolean {
|
||||
@ -1859,10 +1858,7 @@ function createBinder(): (file: SourceFile, options: CompilerOptions) => void {
|
||||
// we'll need to handle the `bindLogicalExpression` scenarios in this state machine, too
|
||||
// For now, though, since the common cases are chained `+`, leaving it recursive is fine
|
||||
const operator = node.operatorToken.kind;
|
||||
if (operator === SyntaxKind.AmpersandAmpersandToken ||
|
||||
operator === SyntaxKind.BarBarToken ||
|
||||
operator === SyntaxKind.QuestionQuestionToken ||
|
||||
isLogicalOrCoalescingAssignmentOperator(operator)) {
|
||||
if (isLogicalOrCoalescingBinaryOperator(operator) || isLogicalOrCoalescingAssignmentOperator(operator)) {
|
||||
if (isTopLevelLogicalExpression(node)) {
|
||||
const postExpressionLabel = createBranchLabel();
|
||||
bindLogicalLikeExpression(node, postExpressionLabel, postExpressionLabel);
|
||||
|
||||
@ -591,6 +591,8 @@ import {
|
||||
isLiteralExpressionOfObject,
|
||||
isLiteralImportTypeNode,
|
||||
isLiteralTypeNode,
|
||||
isLogicalOrCoalescingBinaryExpression,
|
||||
isLogicalOrCoalescingBinaryOperator,
|
||||
isMetaProperty,
|
||||
isMethodDeclaration,
|
||||
isMethodSignature,
|
||||
@ -35561,13 +35563,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
setLeftType(state, leftType);
|
||||
setLastResult(state, /*type*/ undefined);
|
||||
const operator = operatorToken.kind;
|
||||
if (operator === SyntaxKind.AmpersandAmpersandToken || operator === SyntaxKind.BarBarToken || operator === SyntaxKind.QuestionQuestionToken) {
|
||||
if (operator === SyntaxKind.AmpersandAmpersandToken) {
|
||||
let parent = node.parent;
|
||||
while (parent.kind === SyntaxKind.ParenthesizedExpression
|
||||
|| isBinaryExpression(parent) && (parent.operatorToken.kind === SyntaxKind.AmpersandAmpersandToken || parent.operatorToken.kind === SyntaxKind.BarBarToken)) {
|
||||
parent = parent.parent;
|
||||
}
|
||||
if (isLogicalOrCoalescingBinaryOperator(operator)) {
|
||||
let parent = node.parent;
|
||||
while (parent.kind === SyntaxKind.ParenthesizedExpression || isLogicalOrCoalescingBinaryExpression(parent)) {
|
||||
parent = parent.parent;
|
||||
}
|
||||
if (operator === SyntaxKind.AmpersandAmpersandToken || isIfStatement(parent)) {
|
||||
checkTestingKnownTruthyCallableOrAwaitableType(node.left, leftType, isIfStatement(parent) ? parent.thenStatement : undefined);
|
||||
}
|
||||
checkTruthinessOfType(leftType, node.left);
|
||||
@ -35656,7 +35657,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
return checkDestructuringAssignment(left, checkExpression(right, checkMode), checkMode, right.kind === SyntaxKind.ThisKeyword);
|
||||
}
|
||||
let leftType: Type;
|
||||
if (operator === SyntaxKind.AmpersandAmpersandToken || operator === SyntaxKind.BarBarToken || operator === SyntaxKind.QuestionQuestionToken) {
|
||||
if (isLogicalOrCoalescingBinaryOperator(operator)) {
|
||||
leftType = checkTruthinessExpression(left, checkMode);
|
||||
}
|
||||
else {
|
||||
@ -39921,19 +39922,28 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
|
||||
function checkTestingKnownTruthyCallableOrAwaitableType(condExpr: Expression, condType: Type, body?: Statement | Expression) {
|
||||
if (!strictNullChecks) return;
|
||||
bothHelper(condExpr, body);
|
||||
|
||||
function bothHelper(condExpr: Expression, body: Expression | Statement | undefined) {
|
||||
condExpr = skipParentheses(condExpr);
|
||||
|
||||
helper(condExpr, body);
|
||||
while (isBinaryExpression(condExpr) && condExpr.operatorToken.kind === SyntaxKind.BarBarToken) {
|
||||
condExpr = condExpr.left;
|
||||
helper(condExpr, body);
|
||||
|
||||
while (isBinaryExpression(condExpr) && (condExpr.operatorToken.kind === SyntaxKind.BarBarToken || condExpr.operatorToken.kind === SyntaxKind.QuestionQuestionToken)) {
|
||||
condExpr = skipParentheses(condExpr.left);
|
||||
helper(condExpr, body);
|
||||
}
|
||||
}
|
||||
|
||||
function helper(condExpr: Expression, body: Expression | Statement | undefined) {
|
||||
const location = isBinaryExpression(condExpr) &&
|
||||
(condExpr.operatorToken.kind === SyntaxKind.BarBarToken || condExpr.operatorToken.kind === SyntaxKind.AmpersandAmpersandToken)
|
||||
? condExpr.right
|
||||
: condExpr;
|
||||
if (isModuleExportsAccessExpression(location)) return;
|
||||
const location = isLogicalOrCoalescingBinaryExpression(condExpr) ? skipParentheses(condExpr.right) : condExpr;
|
||||
if (isModuleExportsAccessExpression(location)) {
|
||||
return;
|
||||
}
|
||||
if (isLogicalOrCoalescingBinaryExpression(location)) {
|
||||
bothHelper(location, body);
|
||||
return;
|
||||
}
|
||||
const type = location === condExpr ? condType : checkTruthinessExpression(location);
|
||||
const isPropertyExpressionCast = isPropertyAccessExpression(location) && isTypeAssertion(location.expression);
|
||||
if (!(getTypeFacts(type) & TypeFacts.Truthy) || isPropertyExpressionCast) return;
|
||||
@ -39951,7 +39961,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
|
||||
const testedNode = isIdentifier(location) ? location
|
||||
: isPropertyAccessExpression(location) ? location.name
|
||||
: isBinaryExpression(location) && isIdentifier(location.right) ? location.right
|
||||
: undefined;
|
||||
const testedSymbol = testedNode && getSymbolAtLocation(testedNode);
|
||||
if (!testedSymbol && !isPromise) {
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
import {
|
||||
AssignmentExpression,
|
||||
BinaryExpression,
|
||||
Bundle,
|
||||
chainBundle,
|
||||
getNonAssignmentOperatorForCompoundAssignment,
|
||||
@ -14,7 +13,6 @@ import {
|
||||
Node,
|
||||
skipParentheses,
|
||||
SourceFile,
|
||||
SyntaxKind,
|
||||
Token,
|
||||
TransformationContext,
|
||||
TransformFlags,
|
||||
@ -43,16 +41,10 @@ export function transformES2021(context: TransformationContext): (x: SourceFile
|
||||
if ((node.transformFlags & TransformFlags.ContainsES2021) === 0) {
|
||||
return node;
|
||||
}
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.BinaryExpression:
|
||||
const binaryExpression = node as BinaryExpression;
|
||||
if (isLogicalOrCoalescingAssignmentExpression(binaryExpression)) {
|
||||
return transformLogicalAssignment(binaryExpression);
|
||||
}
|
||||
// falls through
|
||||
default:
|
||||
return visitEachChild(node, visitor, context);
|
||||
if (isLogicalOrCoalescingAssignmentExpression(node)) {
|
||||
return transformLogicalAssignment(node);
|
||||
}
|
||||
return visitEachChild(node, visitor, context);
|
||||
}
|
||||
|
||||
function transformLogicalAssignment(binaryExpression: AssignmentExpression<Token<LogicalOrCoalescingAssignmentOperator>>): VisitResult<Node> {
|
||||
|
||||
@ -362,6 +362,7 @@ import {
|
||||
LiteralImportTypeNode,
|
||||
LiteralLikeElementAccessExpression,
|
||||
LiteralLikeNode,
|
||||
LogicalOperator,
|
||||
LogicalOrCoalescingAssignmentOperator,
|
||||
map,
|
||||
mapDefined,
|
||||
@ -6246,11 +6247,13 @@ export function modifierToFlag(token: SyntaxKind): ModifierFlags {
|
||||
return ModifierFlags.None;
|
||||
}
|
||||
|
||||
function isBinaryLogicalOperator(token: SyntaxKind): boolean {
|
||||
return token === SyntaxKind.BarBarToken || token === SyntaxKind.AmpersandAmpersandToken;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export function isLogicalOperator(token: SyntaxKind): boolean {
|
||||
return token === SyntaxKind.BarBarToken
|
||||
|| token === SyntaxKind.AmpersandAmpersandToken
|
||||
|| token === SyntaxKind.ExclamationToken;
|
||||
return isBinaryLogicalOperator(token) || token === SyntaxKind.ExclamationToken;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
@ -6261,8 +6264,18 @@ export function isLogicalOrCoalescingAssignmentOperator(token: SyntaxKind): toke
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export function isLogicalOrCoalescingAssignmentExpression(expr: BinaryExpression): expr is AssignmentExpression<Token<LogicalOrCoalescingAssignmentOperator>> {
|
||||
return isLogicalOrCoalescingAssignmentOperator(expr.operatorToken.kind);
|
||||
export function isLogicalOrCoalescingAssignmentExpression(expr: Node): expr is AssignmentExpression<Token<LogicalOrCoalescingAssignmentOperator>> {
|
||||
return isBinaryExpression(expr) && isLogicalOrCoalescingAssignmentOperator(expr.operatorToken.kind);
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export function isLogicalOrCoalescingBinaryOperator(token: SyntaxKind): token is LogicalOperator | SyntaxKind.QuestionQuestionToken {
|
||||
return isBinaryLogicalOperator(token) || token === SyntaxKind.QuestionQuestionToken;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export function isLogicalOrCoalescingBinaryExpression(expr: Node): expr is BinaryExpression {
|
||||
return isBinaryExpression(expr) && isLogicalOrCoalescingBinaryOperator(expr.operatorToken.kind);
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
|
||||
@ -2,16 +2,40 @@ tests/cases/compiler/truthinessCallExpressionCoercion2.ts(11,5): error TS2774: T
|
||||
tests/cases/compiler/truthinessCallExpressionCoercion2.ts(14,10): error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
|
||||
tests/cases/compiler/truthinessCallExpressionCoercion2.ts(41,18): error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
|
||||
tests/cases/compiler/truthinessCallExpressionCoercion2.ts(44,9): error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
|
||||
tests/cases/compiler/truthinessCallExpressionCoercion2.ts(48,11): error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
|
||||
tests/cases/compiler/truthinessCallExpressionCoercion2.ts(65,46): error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
|
||||
tests/cases/compiler/truthinessCallExpressionCoercion2.ts(76,5): error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
|
||||
tests/cases/compiler/truthinessCallExpressionCoercion2.ts(79,10): error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
|
||||
tests/cases/compiler/truthinessCallExpressionCoercion2.ts(99,5): error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
|
||||
tests/cases/compiler/truthinessCallExpressionCoercion2.ts(109,9): error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
|
||||
tests/cases/compiler/truthinessCallExpressionCoercion2.ts(112,14): error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
|
||||
tests/cases/compiler/truthinessCallExpressionCoercion2.ts(48,9): error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
|
||||
tests/cases/compiler/truthinessCallExpressionCoercion2.ts(52,9): error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
|
||||
tests/cases/compiler/truthinessCallExpressionCoercion2.ts(52,22): error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
|
||||
tests/cases/compiler/truthinessCallExpressionCoercion2.ts(56,9): error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
|
||||
tests/cases/compiler/truthinessCallExpressionCoercion2.ts(60,9): error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
|
||||
tests/cases/compiler/truthinessCallExpressionCoercion2.ts(60,22): error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
|
||||
tests/cases/compiler/truthinessCallExpressionCoercion2.ts(64,11): error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
|
||||
tests/cases/compiler/truthinessCallExpressionCoercion2.ts(93,10): error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
|
||||
tests/cases/compiler/truthinessCallExpressionCoercion2.ts(97,15): error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
|
||||
tests/cases/compiler/truthinessCallExpressionCoercion2.ts(97,28): error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
|
||||
tests/cases/compiler/truthinessCallExpressionCoercion2.ts(101,10): error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
|
||||
tests/cases/compiler/truthinessCallExpressionCoercion2.ts(101,23): error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
|
||||
tests/cases/compiler/truthinessCallExpressionCoercion2.ts(105,15): error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
|
||||
tests/cases/compiler/truthinessCallExpressionCoercion2.ts(105,28): error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
|
||||
tests/cases/compiler/truthinessCallExpressionCoercion2.ts(109,10): error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
|
||||
tests/cases/compiler/truthinessCallExpressionCoercion2.ts(109,23): error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
|
||||
tests/cases/compiler/truthinessCallExpressionCoercion2.ts(116,46): error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
|
||||
tests/cases/compiler/truthinessCallExpressionCoercion2.ts(127,5): error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
|
||||
tests/cases/compiler/truthinessCallExpressionCoercion2.ts(130,10): error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
|
||||
tests/cases/compiler/truthinessCallExpressionCoercion2.ts(150,5): error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
|
||||
tests/cases/compiler/truthinessCallExpressionCoercion2.ts(153,10): error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
|
||||
tests/cases/compiler/truthinessCallExpressionCoercion2.ts(157,15): error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
|
||||
tests/cases/compiler/truthinessCallExpressionCoercion2.ts(157,27): error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
|
||||
tests/cases/compiler/truthinessCallExpressionCoercion2.ts(161,10): error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
|
||||
tests/cases/compiler/truthinessCallExpressionCoercion2.ts(161,22): error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
|
||||
tests/cases/compiler/truthinessCallExpressionCoercion2.ts(165,15): error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
|
||||
tests/cases/compiler/truthinessCallExpressionCoercion2.ts(165,27): error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
|
||||
tests/cases/compiler/truthinessCallExpressionCoercion2.ts(169,10): error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
|
||||
tests/cases/compiler/truthinessCallExpressionCoercion2.ts(169,22): error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
|
||||
tests/cases/compiler/truthinessCallExpressionCoercion2.ts(180,9): error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
|
||||
tests/cases/compiler/truthinessCallExpressionCoercion2.ts(183,14): error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
|
||||
|
||||
|
||||
==== tests/cases/compiler/truthinessCallExpressionCoercion2.ts (11 errors) ====
|
||||
==== tests/cases/compiler/truthinessCallExpressionCoercion2.ts (35 errors) ====
|
||||
declare class A {
|
||||
static from(): string;
|
||||
}
|
||||
@ -66,6 +90,34 @@ tests/cases/compiler/truthinessCallExpressionCoercion2.ts(112,14): error TS2774:
|
||||
!!! error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
|
||||
}
|
||||
|
||||
// error
|
||||
if (required1 || b) {
|
||||
~~~~~~~~~
|
||||
!!! error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
|
||||
}
|
||||
|
||||
// error
|
||||
if (required1 || required2) {
|
||||
~~~~~~~~~
|
||||
!!! error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
|
||||
~~~~~~~~~
|
||||
!!! error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
|
||||
}
|
||||
|
||||
// error
|
||||
if (required1 ?? b) {
|
||||
~~~~~~~~~
|
||||
!!! error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
|
||||
}
|
||||
|
||||
// error
|
||||
if (required1 ?? required2) {
|
||||
~~~~~~~~~
|
||||
!!! error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
|
||||
~~~~~~~~~
|
||||
!!! error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
|
||||
}
|
||||
|
||||
// error
|
||||
if (((required1 && b))) {
|
||||
~~~~~~~~~
|
||||
@ -77,10 +129,63 @@ tests/cases/compiler/truthinessCallExpressionCoercion2.ts(112,14): error TS2774:
|
||||
required1();
|
||||
}
|
||||
|
||||
// ok
|
||||
if (required1 || b) {
|
||||
required1();
|
||||
}
|
||||
|
||||
// ok
|
||||
if (required1 ?? b) {
|
||||
required1();
|
||||
}
|
||||
|
||||
// ok
|
||||
if (b ?? required1) {
|
||||
required1();
|
||||
}
|
||||
|
||||
// ok
|
||||
if (((required1 && b))) {
|
||||
required1();
|
||||
}
|
||||
|
||||
// error, extra parens are on purpose here
|
||||
if ((required1)) {
|
||||
~~~~~~~~~
|
||||
!!! error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
|
||||
}
|
||||
|
||||
// error
|
||||
if (b && (required1 || required2)) {
|
||||
~~~~~~~~~
|
||||
!!! error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
|
||||
~~~~~~~~~
|
||||
!!! error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
|
||||
}
|
||||
|
||||
// error
|
||||
if ((required1 || required2) && b) {
|
||||
~~~~~~~~~
|
||||
!!! error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
|
||||
~~~~~~~~~
|
||||
!!! error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
|
||||
}
|
||||
|
||||
// error
|
||||
if (b && (required1 ?? required2)) {
|
||||
~~~~~~~~~
|
||||
!!! error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
|
||||
~~~~~~~~~
|
||||
!!! error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
|
||||
}
|
||||
|
||||
// error
|
||||
if ((required1 ?? required2) && b) {
|
||||
~~~~~~~~~
|
||||
!!! error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
|
||||
~~~~~~~~~
|
||||
!!! error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
|
||||
}
|
||||
}
|
||||
|
||||
function checksConsole() {
|
||||
@ -129,6 +234,44 @@ tests/cases/compiler/truthinessCallExpressionCoercion2.ts(112,14): error TS2774:
|
||||
x1.a.b.c && x2.a.b.c();
|
||||
~~~~~~~~
|
||||
!!! error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
|
||||
|
||||
// error, extra parens are on purpose here
|
||||
if ((x1.a.b.c)) {
|
||||
~~~~~~~~
|
||||
!!! error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
|
||||
}
|
||||
|
||||
// error
|
||||
if (1 && (x1.a.b.c || x2.a.b.c)) {
|
||||
~~~~~~~~
|
||||
!!! error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
|
||||
~~~~~~~~
|
||||
!!! error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
|
||||
}
|
||||
|
||||
// error
|
||||
if ((x1.a.b.c || x2.a.b.c) && 1) {
|
||||
~~~~~~~~
|
||||
!!! error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
|
||||
~~~~~~~~
|
||||
!!! error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
|
||||
}
|
||||
|
||||
// error
|
||||
if (1 && (x1.a.b.c ?? x2.a.b.c)) {
|
||||
~~~~~~~~
|
||||
!!! error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
|
||||
~~~~~~~~
|
||||
!!! error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
|
||||
}
|
||||
|
||||
// error
|
||||
if ((x1.a.b.c ?? x2.a.b.c) && 1) {
|
||||
~~~~~~~~
|
||||
!!! error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
|
||||
~~~~~~~~
|
||||
!!! error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
|
||||
}
|
||||
}
|
||||
|
||||
class Foo {
|
||||
|
||||
@ -45,6 +45,22 @@ function test(required1: () => boolean, required2: () => boolean, b: boolean, op
|
||||
if (required1 && b) {
|
||||
}
|
||||
|
||||
// error
|
||||
if (required1 || b) {
|
||||
}
|
||||
|
||||
// error
|
||||
if (required1 || required2) {
|
||||
}
|
||||
|
||||
// error
|
||||
if (required1 ?? b) {
|
||||
}
|
||||
|
||||
// error
|
||||
if (required1 ?? required2) {
|
||||
}
|
||||
|
||||
// error
|
||||
if (((required1 && b))) {
|
||||
}
|
||||
@ -54,10 +70,45 @@ function test(required1: () => boolean, required2: () => boolean, b: boolean, op
|
||||
required1();
|
||||
}
|
||||
|
||||
// ok
|
||||
if (required1 || b) {
|
||||
required1();
|
||||
}
|
||||
|
||||
// ok
|
||||
if (required1 ?? b) {
|
||||
required1();
|
||||
}
|
||||
|
||||
// ok
|
||||
if (b ?? required1) {
|
||||
required1();
|
||||
}
|
||||
|
||||
// ok
|
||||
if (((required1 && b))) {
|
||||
required1();
|
||||
}
|
||||
|
||||
// error, extra parens are on purpose here
|
||||
if ((required1)) {
|
||||
}
|
||||
|
||||
// error
|
||||
if (b && (required1 || required2)) {
|
||||
}
|
||||
|
||||
// error
|
||||
if ((required1 || required2) && b) {
|
||||
}
|
||||
|
||||
// error
|
||||
if (b && (required1 ?? required2)) {
|
||||
}
|
||||
|
||||
// error
|
||||
if ((required1 ?? required2) && b) {
|
||||
}
|
||||
}
|
||||
|
||||
function checksConsole() {
|
||||
@ -98,6 +149,26 @@ function checksPropertyAccess() {
|
||||
|
||||
// error
|
||||
x1.a.b.c && x2.a.b.c();
|
||||
|
||||
// error, extra parens are on purpose here
|
||||
if ((x1.a.b.c)) {
|
||||
}
|
||||
|
||||
// error
|
||||
if (1 && (x1.a.b.c || x2.a.b.c)) {
|
||||
}
|
||||
|
||||
// error
|
||||
if ((x1.a.b.c || x2.a.b.c) && 1) {
|
||||
}
|
||||
|
||||
// error
|
||||
if (1 && (x1.a.b.c ?? x2.a.b.c)) {
|
||||
}
|
||||
|
||||
// error
|
||||
if ((x1.a.b.c ?? x2.a.b.c) && 1) {
|
||||
}
|
||||
}
|
||||
|
||||
class Foo {
|
||||
@ -152,6 +223,18 @@ function test(required1, required2, b, optional) {
|
||||
if (required1 && b) {
|
||||
}
|
||||
// error
|
||||
if (required1 || b) {
|
||||
}
|
||||
// error
|
||||
if (required1 || required2) {
|
||||
}
|
||||
// error
|
||||
if (required1 !== null && required1 !== void 0 ? required1 : b) {
|
||||
}
|
||||
// error
|
||||
if (required1 !== null && required1 !== void 0 ? required1 : required2) {
|
||||
}
|
||||
// error
|
||||
if (((required1 && b))) {
|
||||
}
|
||||
// ok
|
||||
@ -159,9 +242,36 @@ function test(required1, required2, b, optional) {
|
||||
required1();
|
||||
}
|
||||
// ok
|
||||
if (required1 || b) {
|
||||
required1();
|
||||
}
|
||||
// ok
|
||||
if (required1 !== null && required1 !== void 0 ? required1 : b) {
|
||||
required1();
|
||||
}
|
||||
// ok
|
||||
if (b !== null && b !== void 0 ? b : required1) {
|
||||
required1();
|
||||
}
|
||||
// ok
|
||||
if (((required1 && b))) {
|
||||
required1();
|
||||
}
|
||||
// error, extra parens are on purpose here
|
||||
if ((required1)) {
|
||||
}
|
||||
// error
|
||||
if (b && (required1 || required2)) {
|
||||
}
|
||||
// error
|
||||
if ((required1 || required2) && b) {
|
||||
}
|
||||
// error
|
||||
if (b && (required1 !== null && required1 !== void 0 ? required1 : required2)) {
|
||||
}
|
||||
// error
|
||||
if ((required1 !== null && required1 !== void 0 ? required1 : required2) && b) {
|
||||
}
|
||||
}
|
||||
function checksConsole() {
|
||||
// error
|
||||
@ -169,6 +279,7 @@ function checksConsole() {
|
||||
(window.console.firebug || (window.console.error && window.console.table));
|
||||
}
|
||||
function checksPropertyAccess() {
|
||||
var _a, _b;
|
||||
var x = {
|
||||
foo: {
|
||||
bar: function () { return true; }
|
||||
@ -193,6 +304,21 @@ function checksPropertyAccess() {
|
||||
};
|
||||
// error
|
||||
x1.a.b.c && x2.a.b.c();
|
||||
// error, extra parens are on purpose here
|
||||
if ((x1.a.b.c)) {
|
||||
}
|
||||
// error
|
||||
if (1 && (x1.a.b.c || x2.a.b.c)) {
|
||||
}
|
||||
// error
|
||||
if ((x1.a.b.c || x2.a.b.c) && 1) {
|
||||
}
|
||||
// error
|
||||
if (1 && ((_a = x1.a.b.c) !== null && _a !== void 0 ? _a : x2.a.b.c)) {
|
||||
}
|
||||
// error
|
||||
if (((_b = x1.a.b.c) !== null && _b !== void 0 ? _b : x2.a.b.c) && 1) {
|
||||
}
|
||||
}
|
||||
var Foo = /** @class */ (function () {
|
||||
function Foo() {
|
||||
|
||||
@ -105,6 +105,30 @@ function test(required1: () => boolean, required2: () => boolean, b: boolean, op
|
||||
>b : Symbol(b, Decl(truthinessCallExpressionCoercion2.ts, 8, 65))
|
||||
}
|
||||
|
||||
// error
|
||||
if (required1 || b) {
|
||||
>required1 : Symbol(required1, Decl(truthinessCallExpressionCoercion2.ts, 8, 14))
|
||||
>b : Symbol(b, Decl(truthinessCallExpressionCoercion2.ts, 8, 65))
|
||||
}
|
||||
|
||||
// error
|
||||
if (required1 || required2) {
|
||||
>required1 : Symbol(required1, Decl(truthinessCallExpressionCoercion2.ts, 8, 14))
|
||||
>required2 : Symbol(required2, Decl(truthinessCallExpressionCoercion2.ts, 8, 39))
|
||||
}
|
||||
|
||||
// error
|
||||
if (required1 ?? b) {
|
||||
>required1 : Symbol(required1, Decl(truthinessCallExpressionCoercion2.ts, 8, 14))
|
||||
>b : Symbol(b, Decl(truthinessCallExpressionCoercion2.ts, 8, 65))
|
||||
}
|
||||
|
||||
// error
|
||||
if (required1 ?? required2) {
|
||||
>required1 : Symbol(required1, Decl(truthinessCallExpressionCoercion2.ts, 8, 14))
|
||||
>required2 : Symbol(required2, Decl(truthinessCallExpressionCoercion2.ts, 8, 39))
|
||||
}
|
||||
|
||||
// error
|
||||
if (((required1 && b))) {
|
||||
>required1 : Symbol(required1, Decl(truthinessCallExpressionCoercion2.ts, 8, 14))
|
||||
@ -120,6 +144,33 @@ function test(required1: () => boolean, required2: () => boolean, b: boolean, op
|
||||
>required1 : Symbol(required1, Decl(truthinessCallExpressionCoercion2.ts, 8, 14))
|
||||
}
|
||||
|
||||
// ok
|
||||
if (required1 || b) {
|
||||
>required1 : Symbol(required1, Decl(truthinessCallExpressionCoercion2.ts, 8, 14))
|
||||
>b : Symbol(b, Decl(truthinessCallExpressionCoercion2.ts, 8, 65))
|
||||
|
||||
required1();
|
||||
>required1 : Symbol(required1, Decl(truthinessCallExpressionCoercion2.ts, 8, 14))
|
||||
}
|
||||
|
||||
// ok
|
||||
if (required1 ?? b) {
|
||||
>required1 : Symbol(required1, Decl(truthinessCallExpressionCoercion2.ts, 8, 14))
|
||||
>b : Symbol(b, Decl(truthinessCallExpressionCoercion2.ts, 8, 65))
|
||||
|
||||
required1();
|
||||
>required1 : Symbol(required1, Decl(truthinessCallExpressionCoercion2.ts, 8, 14))
|
||||
}
|
||||
|
||||
// ok
|
||||
if (b ?? required1) {
|
||||
>b : Symbol(b, Decl(truthinessCallExpressionCoercion2.ts, 8, 65))
|
||||
>required1 : Symbol(required1, Decl(truthinessCallExpressionCoercion2.ts, 8, 14))
|
||||
|
||||
required1();
|
||||
>required1 : Symbol(required1, Decl(truthinessCallExpressionCoercion2.ts, 8, 14))
|
||||
}
|
||||
|
||||
// ok
|
||||
if (((required1 && b))) {
|
||||
>required1 : Symbol(required1, Decl(truthinessCallExpressionCoercion2.ts, 8, 14))
|
||||
@ -128,10 +179,43 @@ function test(required1: () => boolean, required2: () => boolean, b: boolean, op
|
||||
required1();
|
||||
>required1 : Symbol(required1, Decl(truthinessCallExpressionCoercion2.ts, 8, 14))
|
||||
}
|
||||
|
||||
// error, extra parens are on purpose here
|
||||
if ((required1)) {
|
||||
>required1 : Symbol(required1, Decl(truthinessCallExpressionCoercion2.ts, 8, 14))
|
||||
}
|
||||
|
||||
// error
|
||||
if (b && (required1 || required2)) {
|
||||
>b : Symbol(b, Decl(truthinessCallExpressionCoercion2.ts, 8, 65))
|
||||
>required1 : Symbol(required1, Decl(truthinessCallExpressionCoercion2.ts, 8, 14))
|
||||
>required2 : Symbol(required2, Decl(truthinessCallExpressionCoercion2.ts, 8, 39))
|
||||
}
|
||||
|
||||
// error
|
||||
if ((required1 || required2) && b) {
|
||||
>required1 : Symbol(required1, Decl(truthinessCallExpressionCoercion2.ts, 8, 14))
|
||||
>required2 : Symbol(required2, Decl(truthinessCallExpressionCoercion2.ts, 8, 39))
|
||||
>b : Symbol(b, Decl(truthinessCallExpressionCoercion2.ts, 8, 65))
|
||||
}
|
||||
|
||||
// error
|
||||
if (b && (required1 ?? required2)) {
|
||||
>b : Symbol(b, Decl(truthinessCallExpressionCoercion2.ts, 8, 65))
|
||||
>required1 : Symbol(required1, Decl(truthinessCallExpressionCoercion2.ts, 8, 14))
|
||||
>required2 : Symbol(required2, Decl(truthinessCallExpressionCoercion2.ts, 8, 39))
|
||||
}
|
||||
|
||||
// error
|
||||
if ((required1 ?? required2) && b) {
|
||||
>required1 : Symbol(required1, Decl(truthinessCallExpressionCoercion2.ts, 8, 14))
|
||||
>required2 : Symbol(required2, Decl(truthinessCallExpressionCoercion2.ts, 8, 39))
|
||||
>b : Symbol(b, Decl(truthinessCallExpressionCoercion2.ts, 8, 65))
|
||||
}
|
||||
}
|
||||
|
||||
function checksConsole() {
|
||||
>checksConsole : Symbol(checksConsole, Decl(truthinessCallExpressionCoercion2.ts, 59, 1))
|
||||
>checksConsole : Symbol(checksConsole, Decl(truthinessCallExpressionCoercion2.ts, 110, 1))
|
||||
|
||||
// error
|
||||
typeof window !== 'undefined' && window.console &&
|
||||
@ -157,70 +241,70 @@ function checksConsole() {
|
||||
}
|
||||
|
||||
function checksPropertyAccess() {
|
||||
>checksPropertyAccess : Symbol(checksPropertyAccess, Decl(truthinessCallExpressionCoercion2.ts, 65, 1))
|
||||
>checksPropertyAccess : Symbol(checksPropertyAccess, Decl(truthinessCallExpressionCoercion2.ts, 116, 1))
|
||||
|
||||
const x = {
|
||||
>x : Symbol(x, Decl(truthinessCallExpressionCoercion2.ts, 68, 9))
|
||||
>x : Symbol(x, Decl(truthinessCallExpressionCoercion2.ts, 119, 9))
|
||||
|
||||
foo: {
|
||||
>foo : Symbol(foo, Decl(truthinessCallExpressionCoercion2.ts, 68, 15))
|
||||
>foo : Symbol(foo, Decl(truthinessCallExpressionCoercion2.ts, 119, 15))
|
||||
|
||||
bar() { return true; }
|
||||
>bar : Symbol(bar, Decl(truthinessCallExpressionCoercion2.ts, 69, 14))
|
||||
>bar : Symbol(bar, Decl(truthinessCallExpressionCoercion2.ts, 120, 14))
|
||||
}
|
||||
}
|
||||
|
||||
// error
|
||||
x.foo.bar && console.log('x.foo.bar');
|
||||
>x.foo.bar : Symbol(bar, Decl(truthinessCallExpressionCoercion2.ts, 69, 14))
|
||||
>x.foo : Symbol(foo, Decl(truthinessCallExpressionCoercion2.ts, 68, 15))
|
||||
>x : Symbol(x, Decl(truthinessCallExpressionCoercion2.ts, 68, 9))
|
||||
>foo : Symbol(foo, Decl(truthinessCallExpressionCoercion2.ts, 68, 15))
|
||||
>bar : Symbol(bar, Decl(truthinessCallExpressionCoercion2.ts, 69, 14))
|
||||
>x.foo.bar : Symbol(bar, Decl(truthinessCallExpressionCoercion2.ts, 120, 14))
|
||||
>x.foo : Symbol(foo, Decl(truthinessCallExpressionCoercion2.ts, 119, 15))
|
||||
>x : Symbol(x, Decl(truthinessCallExpressionCoercion2.ts, 119, 9))
|
||||
>foo : Symbol(foo, Decl(truthinessCallExpressionCoercion2.ts, 119, 15))
|
||||
>bar : Symbol(bar, Decl(truthinessCallExpressionCoercion2.ts, 120, 14))
|
||||
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
|
||||
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
|
||||
// error
|
||||
1 && x.foo.bar && console.log('x.foo.bar');
|
||||
>x.foo.bar : Symbol(bar, Decl(truthinessCallExpressionCoercion2.ts, 69, 14))
|
||||
>x.foo : Symbol(foo, Decl(truthinessCallExpressionCoercion2.ts, 68, 15))
|
||||
>x : Symbol(x, Decl(truthinessCallExpressionCoercion2.ts, 68, 9))
|
||||
>foo : Symbol(foo, Decl(truthinessCallExpressionCoercion2.ts, 68, 15))
|
||||
>bar : Symbol(bar, Decl(truthinessCallExpressionCoercion2.ts, 69, 14))
|
||||
>x.foo.bar : Symbol(bar, Decl(truthinessCallExpressionCoercion2.ts, 120, 14))
|
||||
>x.foo : Symbol(foo, Decl(truthinessCallExpressionCoercion2.ts, 119, 15))
|
||||
>x : Symbol(x, Decl(truthinessCallExpressionCoercion2.ts, 119, 9))
|
||||
>foo : Symbol(foo, Decl(truthinessCallExpressionCoercion2.ts, 119, 15))
|
||||
>bar : Symbol(bar, Decl(truthinessCallExpressionCoercion2.ts, 120, 14))
|
||||
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
|
||||
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
|
||||
// ok
|
||||
x.foo.bar && x.foo.bar();
|
||||
>x.foo.bar : Symbol(bar, Decl(truthinessCallExpressionCoercion2.ts, 69, 14))
|
||||
>x.foo : Symbol(foo, Decl(truthinessCallExpressionCoercion2.ts, 68, 15))
|
||||
>x : Symbol(x, Decl(truthinessCallExpressionCoercion2.ts, 68, 9))
|
||||
>foo : Symbol(foo, Decl(truthinessCallExpressionCoercion2.ts, 68, 15))
|
||||
>bar : Symbol(bar, Decl(truthinessCallExpressionCoercion2.ts, 69, 14))
|
||||
>x.foo.bar : Symbol(bar, Decl(truthinessCallExpressionCoercion2.ts, 69, 14))
|
||||
>x.foo : Symbol(foo, Decl(truthinessCallExpressionCoercion2.ts, 68, 15))
|
||||
>x : Symbol(x, Decl(truthinessCallExpressionCoercion2.ts, 68, 9))
|
||||
>foo : Symbol(foo, Decl(truthinessCallExpressionCoercion2.ts, 68, 15))
|
||||
>bar : Symbol(bar, Decl(truthinessCallExpressionCoercion2.ts, 69, 14))
|
||||
>x.foo.bar : Symbol(bar, Decl(truthinessCallExpressionCoercion2.ts, 120, 14))
|
||||
>x.foo : Symbol(foo, Decl(truthinessCallExpressionCoercion2.ts, 119, 15))
|
||||
>x : Symbol(x, Decl(truthinessCallExpressionCoercion2.ts, 119, 9))
|
||||
>foo : Symbol(foo, Decl(truthinessCallExpressionCoercion2.ts, 119, 15))
|
||||
>bar : Symbol(bar, Decl(truthinessCallExpressionCoercion2.ts, 120, 14))
|
||||
>x.foo.bar : Symbol(bar, Decl(truthinessCallExpressionCoercion2.ts, 120, 14))
|
||||
>x.foo : Symbol(foo, Decl(truthinessCallExpressionCoercion2.ts, 119, 15))
|
||||
>x : Symbol(x, Decl(truthinessCallExpressionCoercion2.ts, 119, 9))
|
||||
>foo : Symbol(foo, Decl(truthinessCallExpressionCoercion2.ts, 119, 15))
|
||||
>bar : Symbol(bar, Decl(truthinessCallExpressionCoercion2.ts, 120, 14))
|
||||
|
||||
// ok
|
||||
x.foo.bar && 1 && x.foo.bar();
|
||||
>x.foo.bar : Symbol(bar, Decl(truthinessCallExpressionCoercion2.ts, 69, 14))
|
||||
>x.foo : Symbol(foo, Decl(truthinessCallExpressionCoercion2.ts, 68, 15))
|
||||
>x : Symbol(x, Decl(truthinessCallExpressionCoercion2.ts, 68, 9))
|
||||
>foo : Symbol(foo, Decl(truthinessCallExpressionCoercion2.ts, 68, 15))
|
||||
>bar : Symbol(bar, Decl(truthinessCallExpressionCoercion2.ts, 69, 14))
|
||||
>x.foo.bar : Symbol(bar, Decl(truthinessCallExpressionCoercion2.ts, 69, 14))
|
||||
>x.foo : Symbol(foo, Decl(truthinessCallExpressionCoercion2.ts, 68, 15))
|
||||
>x : Symbol(x, Decl(truthinessCallExpressionCoercion2.ts, 68, 9))
|
||||
>foo : Symbol(foo, Decl(truthinessCallExpressionCoercion2.ts, 68, 15))
|
||||
>bar : Symbol(bar, Decl(truthinessCallExpressionCoercion2.ts, 69, 14))
|
||||
>x.foo.bar : Symbol(bar, Decl(truthinessCallExpressionCoercion2.ts, 120, 14))
|
||||
>x.foo : Symbol(foo, Decl(truthinessCallExpressionCoercion2.ts, 119, 15))
|
||||
>x : Symbol(x, Decl(truthinessCallExpressionCoercion2.ts, 119, 9))
|
||||
>foo : Symbol(foo, Decl(truthinessCallExpressionCoercion2.ts, 119, 15))
|
||||
>bar : Symbol(bar, Decl(truthinessCallExpressionCoercion2.ts, 120, 14))
|
||||
>x.foo.bar : Symbol(bar, Decl(truthinessCallExpressionCoercion2.ts, 120, 14))
|
||||
>x.foo : Symbol(foo, Decl(truthinessCallExpressionCoercion2.ts, 119, 15))
|
||||
>x : Symbol(x, Decl(truthinessCallExpressionCoercion2.ts, 119, 9))
|
||||
>foo : Symbol(foo, Decl(truthinessCallExpressionCoercion2.ts, 119, 15))
|
||||
>bar : Symbol(bar, Decl(truthinessCallExpressionCoercion2.ts, 120, 14))
|
||||
|
||||
// ok
|
||||
const y = A.from && (A.from as Function) !== B.from ? true : false;
|
||||
>y : Symbol(y, Decl(truthinessCallExpressionCoercion2.ts, 87, 9))
|
||||
>y : Symbol(y, Decl(truthinessCallExpressionCoercion2.ts, 138, 9))
|
||||
>A.from : Symbol(A.from, Decl(truthinessCallExpressionCoercion2.ts, 0, 17))
|
||||
>A : Symbol(A, Decl(truthinessCallExpressionCoercion2.ts, 0, 0))
|
||||
>from : Symbol(A.from, Decl(truthinessCallExpressionCoercion2.ts, 0, 17))
|
||||
@ -233,98 +317,181 @@ function checksPropertyAccess() {
|
||||
>from : Symbol(B.from, Decl(truthinessCallExpressionCoercion2.ts, 4, 17))
|
||||
|
||||
y;
|
||||
>y : Symbol(y, Decl(truthinessCallExpressionCoercion2.ts, 87, 9))
|
||||
>y : Symbol(y, Decl(truthinessCallExpressionCoercion2.ts, 138, 9))
|
||||
|
||||
const x1 = {
|
||||
>x1 : Symbol(x1, Decl(truthinessCallExpressionCoercion2.ts, 90, 9))
|
||||
>x1 : Symbol(x1, Decl(truthinessCallExpressionCoercion2.ts, 141, 9))
|
||||
|
||||
a: { b: { c: () => {} } }
|
||||
>a : Symbol(a, Decl(truthinessCallExpressionCoercion2.ts, 90, 16))
|
||||
>b : Symbol(b, Decl(truthinessCallExpressionCoercion2.ts, 91, 12))
|
||||
>c : Symbol(c, Decl(truthinessCallExpressionCoercion2.ts, 91, 17))
|
||||
>a : Symbol(a, Decl(truthinessCallExpressionCoercion2.ts, 141, 16))
|
||||
>b : Symbol(b, Decl(truthinessCallExpressionCoercion2.ts, 142, 12))
|
||||
>c : Symbol(c, Decl(truthinessCallExpressionCoercion2.ts, 142, 17))
|
||||
}
|
||||
const x2 = {
|
||||
>x2 : Symbol(x2, Decl(truthinessCallExpressionCoercion2.ts, 93, 9))
|
||||
>x2 : Symbol(x2, Decl(truthinessCallExpressionCoercion2.ts, 144, 9))
|
||||
|
||||
a: { b: { c: () => {} } }
|
||||
>a : Symbol(a, Decl(truthinessCallExpressionCoercion2.ts, 93, 16))
|
||||
>b : Symbol(b, Decl(truthinessCallExpressionCoercion2.ts, 94, 12))
|
||||
>c : Symbol(c, Decl(truthinessCallExpressionCoercion2.ts, 94, 17))
|
||||
>a : Symbol(a, Decl(truthinessCallExpressionCoercion2.ts, 144, 16))
|
||||
>b : Symbol(b, Decl(truthinessCallExpressionCoercion2.ts, 145, 12))
|
||||
>c : Symbol(c, Decl(truthinessCallExpressionCoercion2.ts, 145, 17))
|
||||
}
|
||||
|
||||
// error
|
||||
x1.a.b.c && x2.a.b.c();
|
||||
>x1.a.b.c : Symbol(c, Decl(truthinessCallExpressionCoercion2.ts, 91, 17))
|
||||
>x1.a.b : Symbol(b, Decl(truthinessCallExpressionCoercion2.ts, 91, 12))
|
||||
>x1.a : Symbol(a, Decl(truthinessCallExpressionCoercion2.ts, 90, 16))
|
||||
>x1 : Symbol(x1, Decl(truthinessCallExpressionCoercion2.ts, 90, 9))
|
||||
>a : Symbol(a, Decl(truthinessCallExpressionCoercion2.ts, 90, 16))
|
||||
>b : Symbol(b, Decl(truthinessCallExpressionCoercion2.ts, 91, 12))
|
||||
>c : Symbol(c, Decl(truthinessCallExpressionCoercion2.ts, 91, 17))
|
||||
>x2.a.b.c : Symbol(c, Decl(truthinessCallExpressionCoercion2.ts, 94, 17))
|
||||
>x2.a.b : Symbol(b, Decl(truthinessCallExpressionCoercion2.ts, 94, 12))
|
||||
>x2.a : Symbol(a, Decl(truthinessCallExpressionCoercion2.ts, 93, 16))
|
||||
>x2 : Symbol(x2, Decl(truthinessCallExpressionCoercion2.ts, 93, 9))
|
||||
>a : Symbol(a, Decl(truthinessCallExpressionCoercion2.ts, 93, 16))
|
||||
>b : Symbol(b, Decl(truthinessCallExpressionCoercion2.ts, 94, 12))
|
||||
>c : Symbol(c, Decl(truthinessCallExpressionCoercion2.ts, 94, 17))
|
||||
>x1.a.b.c : Symbol(c, Decl(truthinessCallExpressionCoercion2.ts, 142, 17))
|
||||
>x1.a.b : Symbol(b, Decl(truthinessCallExpressionCoercion2.ts, 142, 12))
|
||||
>x1.a : Symbol(a, Decl(truthinessCallExpressionCoercion2.ts, 141, 16))
|
||||
>x1 : Symbol(x1, Decl(truthinessCallExpressionCoercion2.ts, 141, 9))
|
||||
>a : Symbol(a, Decl(truthinessCallExpressionCoercion2.ts, 141, 16))
|
||||
>b : Symbol(b, Decl(truthinessCallExpressionCoercion2.ts, 142, 12))
|
||||
>c : Symbol(c, Decl(truthinessCallExpressionCoercion2.ts, 142, 17))
|
||||
>x2.a.b.c : Symbol(c, Decl(truthinessCallExpressionCoercion2.ts, 145, 17))
|
||||
>x2.a.b : Symbol(b, Decl(truthinessCallExpressionCoercion2.ts, 145, 12))
|
||||
>x2.a : Symbol(a, Decl(truthinessCallExpressionCoercion2.ts, 144, 16))
|
||||
>x2 : Symbol(x2, Decl(truthinessCallExpressionCoercion2.ts, 144, 9))
|
||||
>a : Symbol(a, Decl(truthinessCallExpressionCoercion2.ts, 144, 16))
|
||||
>b : Symbol(b, Decl(truthinessCallExpressionCoercion2.ts, 145, 12))
|
||||
>c : Symbol(c, Decl(truthinessCallExpressionCoercion2.ts, 145, 17))
|
||||
|
||||
// error, extra parens are on purpose here
|
||||
if ((x1.a.b.c)) {
|
||||
>x1.a.b.c : Symbol(c, Decl(truthinessCallExpressionCoercion2.ts, 142, 17))
|
||||
>x1.a.b : Symbol(b, Decl(truthinessCallExpressionCoercion2.ts, 142, 12))
|
||||
>x1.a : Symbol(a, Decl(truthinessCallExpressionCoercion2.ts, 141, 16))
|
||||
>x1 : Symbol(x1, Decl(truthinessCallExpressionCoercion2.ts, 141, 9))
|
||||
>a : Symbol(a, Decl(truthinessCallExpressionCoercion2.ts, 141, 16))
|
||||
>b : Symbol(b, Decl(truthinessCallExpressionCoercion2.ts, 142, 12))
|
||||
>c : Symbol(c, Decl(truthinessCallExpressionCoercion2.ts, 142, 17))
|
||||
}
|
||||
|
||||
// error
|
||||
if (1 && (x1.a.b.c || x2.a.b.c)) {
|
||||
>x1.a.b.c : Symbol(c, Decl(truthinessCallExpressionCoercion2.ts, 142, 17))
|
||||
>x1.a.b : Symbol(b, Decl(truthinessCallExpressionCoercion2.ts, 142, 12))
|
||||
>x1.a : Symbol(a, Decl(truthinessCallExpressionCoercion2.ts, 141, 16))
|
||||
>x1 : Symbol(x1, Decl(truthinessCallExpressionCoercion2.ts, 141, 9))
|
||||
>a : Symbol(a, Decl(truthinessCallExpressionCoercion2.ts, 141, 16))
|
||||
>b : Symbol(b, Decl(truthinessCallExpressionCoercion2.ts, 142, 12))
|
||||
>c : Symbol(c, Decl(truthinessCallExpressionCoercion2.ts, 142, 17))
|
||||
>x2.a.b.c : Symbol(c, Decl(truthinessCallExpressionCoercion2.ts, 145, 17))
|
||||
>x2.a.b : Symbol(b, Decl(truthinessCallExpressionCoercion2.ts, 145, 12))
|
||||
>x2.a : Symbol(a, Decl(truthinessCallExpressionCoercion2.ts, 144, 16))
|
||||
>x2 : Symbol(x2, Decl(truthinessCallExpressionCoercion2.ts, 144, 9))
|
||||
>a : Symbol(a, Decl(truthinessCallExpressionCoercion2.ts, 144, 16))
|
||||
>b : Symbol(b, Decl(truthinessCallExpressionCoercion2.ts, 145, 12))
|
||||
>c : Symbol(c, Decl(truthinessCallExpressionCoercion2.ts, 145, 17))
|
||||
}
|
||||
|
||||
// error
|
||||
if ((x1.a.b.c || x2.a.b.c) && 1) {
|
||||
>x1.a.b.c : Symbol(c, Decl(truthinessCallExpressionCoercion2.ts, 142, 17))
|
||||
>x1.a.b : Symbol(b, Decl(truthinessCallExpressionCoercion2.ts, 142, 12))
|
||||
>x1.a : Symbol(a, Decl(truthinessCallExpressionCoercion2.ts, 141, 16))
|
||||
>x1 : Symbol(x1, Decl(truthinessCallExpressionCoercion2.ts, 141, 9))
|
||||
>a : Symbol(a, Decl(truthinessCallExpressionCoercion2.ts, 141, 16))
|
||||
>b : Symbol(b, Decl(truthinessCallExpressionCoercion2.ts, 142, 12))
|
||||
>c : Symbol(c, Decl(truthinessCallExpressionCoercion2.ts, 142, 17))
|
||||
>x2.a.b.c : Symbol(c, Decl(truthinessCallExpressionCoercion2.ts, 145, 17))
|
||||
>x2.a.b : Symbol(b, Decl(truthinessCallExpressionCoercion2.ts, 145, 12))
|
||||
>x2.a : Symbol(a, Decl(truthinessCallExpressionCoercion2.ts, 144, 16))
|
||||
>x2 : Symbol(x2, Decl(truthinessCallExpressionCoercion2.ts, 144, 9))
|
||||
>a : Symbol(a, Decl(truthinessCallExpressionCoercion2.ts, 144, 16))
|
||||
>b : Symbol(b, Decl(truthinessCallExpressionCoercion2.ts, 145, 12))
|
||||
>c : Symbol(c, Decl(truthinessCallExpressionCoercion2.ts, 145, 17))
|
||||
}
|
||||
|
||||
// error
|
||||
if (1 && (x1.a.b.c ?? x2.a.b.c)) {
|
||||
>x1.a.b.c : Symbol(c, Decl(truthinessCallExpressionCoercion2.ts, 142, 17))
|
||||
>x1.a.b : Symbol(b, Decl(truthinessCallExpressionCoercion2.ts, 142, 12))
|
||||
>x1.a : Symbol(a, Decl(truthinessCallExpressionCoercion2.ts, 141, 16))
|
||||
>x1 : Symbol(x1, Decl(truthinessCallExpressionCoercion2.ts, 141, 9))
|
||||
>a : Symbol(a, Decl(truthinessCallExpressionCoercion2.ts, 141, 16))
|
||||
>b : Symbol(b, Decl(truthinessCallExpressionCoercion2.ts, 142, 12))
|
||||
>c : Symbol(c, Decl(truthinessCallExpressionCoercion2.ts, 142, 17))
|
||||
>x2.a.b.c : Symbol(c, Decl(truthinessCallExpressionCoercion2.ts, 145, 17))
|
||||
>x2.a.b : Symbol(b, Decl(truthinessCallExpressionCoercion2.ts, 145, 12))
|
||||
>x2.a : Symbol(a, Decl(truthinessCallExpressionCoercion2.ts, 144, 16))
|
||||
>x2 : Symbol(x2, Decl(truthinessCallExpressionCoercion2.ts, 144, 9))
|
||||
>a : Symbol(a, Decl(truthinessCallExpressionCoercion2.ts, 144, 16))
|
||||
>b : Symbol(b, Decl(truthinessCallExpressionCoercion2.ts, 145, 12))
|
||||
>c : Symbol(c, Decl(truthinessCallExpressionCoercion2.ts, 145, 17))
|
||||
}
|
||||
|
||||
// error
|
||||
if ((x1.a.b.c ?? x2.a.b.c) && 1) {
|
||||
>x1.a.b.c : Symbol(c, Decl(truthinessCallExpressionCoercion2.ts, 142, 17))
|
||||
>x1.a.b : Symbol(b, Decl(truthinessCallExpressionCoercion2.ts, 142, 12))
|
||||
>x1.a : Symbol(a, Decl(truthinessCallExpressionCoercion2.ts, 141, 16))
|
||||
>x1 : Symbol(x1, Decl(truthinessCallExpressionCoercion2.ts, 141, 9))
|
||||
>a : Symbol(a, Decl(truthinessCallExpressionCoercion2.ts, 141, 16))
|
||||
>b : Symbol(b, Decl(truthinessCallExpressionCoercion2.ts, 142, 12))
|
||||
>c : Symbol(c, Decl(truthinessCallExpressionCoercion2.ts, 142, 17))
|
||||
>x2.a.b.c : Symbol(c, Decl(truthinessCallExpressionCoercion2.ts, 145, 17))
|
||||
>x2.a.b : Symbol(b, Decl(truthinessCallExpressionCoercion2.ts, 145, 12))
|
||||
>x2.a : Symbol(a, Decl(truthinessCallExpressionCoercion2.ts, 144, 16))
|
||||
>x2 : Symbol(x2, Decl(truthinessCallExpressionCoercion2.ts, 144, 9))
|
||||
>a : Symbol(a, Decl(truthinessCallExpressionCoercion2.ts, 144, 16))
|
||||
>b : Symbol(b, Decl(truthinessCallExpressionCoercion2.ts, 145, 12))
|
||||
>c : Symbol(c, Decl(truthinessCallExpressionCoercion2.ts, 145, 17))
|
||||
}
|
||||
}
|
||||
|
||||
class Foo {
|
||||
>Foo : Symbol(Foo, Decl(truthinessCallExpressionCoercion2.ts, 99, 1))
|
||||
>Foo : Symbol(Foo, Decl(truthinessCallExpressionCoercion2.ts, 170, 1))
|
||||
|
||||
optional?: () => boolean;
|
||||
>optional : Symbol(Foo.optional, Decl(truthinessCallExpressionCoercion2.ts, 101, 11))
|
||||
>optional : Symbol(Foo.optional, Decl(truthinessCallExpressionCoercion2.ts, 172, 11))
|
||||
|
||||
required() {
|
||||
>required : Symbol(Foo.required, Decl(truthinessCallExpressionCoercion2.ts, 102, 29))
|
||||
>required : Symbol(Foo.required, Decl(truthinessCallExpressionCoercion2.ts, 173, 29))
|
||||
|
||||
return true;
|
||||
}
|
||||
test() {
|
||||
>test : Symbol(Foo.test, Decl(truthinessCallExpressionCoercion2.ts, 105, 5))
|
||||
>test : Symbol(Foo.test, Decl(truthinessCallExpressionCoercion2.ts, 176, 5))
|
||||
|
||||
// error
|
||||
this.required && console.log('required');
|
||||
>this.required : Symbol(Foo.required, Decl(truthinessCallExpressionCoercion2.ts, 102, 29))
|
||||
>this : Symbol(Foo, Decl(truthinessCallExpressionCoercion2.ts, 99, 1))
|
||||
>required : Symbol(Foo.required, Decl(truthinessCallExpressionCoercion2.ts, 102, 29))
|
||||
>this.required : Symbol(Foo.required, Decl(truthinessCallExpressionCoercion2.ts, 173, 29))
|
||||
>this : Symbol(Foo, Decl(truthinessCallExpressionCoercion2.ts, 170, 1))
|
||||
>required : Symbol(Foo.required, Decl(truthinessCallExpressionCoercion2.ts, 173, 29))
|
||||
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
|
||||
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
|
||||
// error
|
||||
1 && this.required && console.log('required');
|
||||
>this.required : Symbol(Foo.required, Decl(truthinessCallExpressionCoercion2.ts, 102, 29))
|
||||
>this : Symbol(Foo, Decl(truthinessCallExpressionCoercion2.ts, 99, 1))
|
||||
>required : Symbol(Foo.required, Decl(truthinessCallExpressionCoercion2.ts, 102, 29))
|
||||
>this.required : Symbol(Foo.required, Decl(truthinessCallExpressionCoercion2.ts, 173, 29))
|
||||
>this : Symbol(Foo, Decl(truthinessCallExpressionCoercion2.ts, 170, 1))
|
||||
>required : Symbol(Foo.required, Decl(truthinessCallExpressionCoercion2.ts, 173, 29))
|
||||
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
|
||||
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
|
||||
// ok
|
||||
this.required && this.required();
|
||||
>this.required : Symbol(Foo.required, Decl(truthinessCallExpressionCoercion2.ts, 102, 29))
|
||||
>this : Symbol(Foo, Decl(truthinessCallExpressionCoercion2.ts, 99, 1))
|
||||
>required : Symbol(Foo.required, Decl(truthinessCallExpressionCoercion2.ts, 102, 29))
|
||||
>this.required : Symbol(Foo.required, Decl(truthinessCallExpressionCoercion2.ts, 102, 29))
|
||||
>this : Symbol(Foo, Decl(truthinessCallExpressionCoercion2.ts, 99, 1))
|
||||
>required : Symbol(Foo.required, Decl(truthinessCallExpressionCoercion2.ts, 102, 29))
|
||||
>this.required : Symbol(Foo.required, Decl(truthinessCallExpressionCoercion2.ts, 173, 29))
|
||||
>this : Symbol(Foo, Decl(truthinessCallExpressionCoercion2.ts, 170, 1))
|
||||
>required : Symbol(Foo.required, Decl(truthinessCallExpressionCoercion2.ts, 173, 29))
|
||||
>this.required : Symbol(Foo.required, Decl(truthinessCallExpressionCoercion2.ts, 173, 29))
|
||||
>this : Symbol(Foo, Decl(truthinessCallExpressionCoercion2.ts, 170, 1))
|
||||
>required : Symbol(Foo.required, Decl(truthinessCallExpressionCoercion2.ts, 173, 29))
|
||||
|
||||
// ok
|
||||
this.required && 1 && this.required();
|
||||
>this.required : Symbol(Foo.required, Decl(truthinessCallExpressionCoercion2.ts, 102, 29))
|
||||
>this : Symbol(Foo, Decl(truthinessCallExpressionCoercion2.ts, 99, 1))
|
||||
>required : Symbol(Foo.required, Decl(truthinessCallExpressionCoercion2.ts, 102, 29))
|
||||
>this.required : Symbol(Foo.required, Decl(truthinessCallExpressionCoercion2.ts, 102, 29))
|
||||
>this : Symbol(Foo, Decl(truthinessCallExpressionCoercion2.ts, 99, 1))
|
||||
>required : Symbol(Foo.required, Decl(truthinessCallExpressionCoercion2.ts, 102, 29))
|
||||
>this.required : Symbol(Foo.required, Decl(truthinessCallExpressionCoercion2.ts, 173, 29))
|
||||
>this : Symbol(Foo, Decl(truthinessCallExpressionCoercion2.ts, 170, 1))
|
||||
>required : Symbol(Foo.required, Decl(truthinessCallExpressionCoercion2.ts, 173, 29))
|
||||
>this.required : Symbol(Foo.required, Decl(truthinessCallExpressionCoercion2.ts, 173, 29))
|
||||
>this : Symbol(Foo, Decl(truthinessCallExpressionCoercion2.ts, 170, 1))
|
||||
>required : Symbol(Foo.required, Decl(truthinessCallExpressionCoercion2.ts, 173, 29))
|
||||
|
||||
// ok
|
||||
1 && this.optional && console.log('optional');
|
||||
>this.optional : Symbol(Foo.optional, Decl(truthinessCallExpressionCoercion2.ts, 101, 11))
|
||||
>this : Symbol(Foo, Decl(truthinessCallExpressionCoercion2.ts, 99, 1))
|
||||
>optional : Symbol(Foo.optional, Decl(truthinessCallExpressionCoercion2.ts, 101, 11))
|
||||
>this.optional : Symbol(Foo.optional, Decl(truthinessCallExpressionCoercion2.ts, 172, 11))
|
||||
>this : Symbol(Foo, Decl(truthinessCallExpressionCoercion2.ts, 170, 1))
|
||||
>optional : Symbol(Foo.optional, Decl(truthinessCallExpressionCoercion2.ts, 172, 11))
|
||||
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
|
||||
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
|
||||
@ -154,6 +154,34 @@ function test(required1: () => boolean, required2: () => boolean, b: boolean, op
|
||||
>b : boolean
|
||||
}
|
||||
|
||||
// error
|
||||
if (required1 || b) {
|
||||
>required1 || b : () => boolean
|
||||
>required1 : () => boolean
|
||||
>b : boolean
|
||||
}
|
||||
|
||||
// error
|
||||
if (required1 || required2) {
|
||||
>required1 || required2 : () => boolean
|
||||
>required1 : () => boolean
|
||||
>required2 : () => boolean
|
||||
}
|
||||
|
||||
// error
|
||||
if (required1 ?? b) {
|
||||
>required1 ?? b : () => boolean
|
||||
>required1 : () => boolean
|
||||
>b : boolean
|
||||
}
|
||||
|
||||
// error
|
||||
if (required1 ?? required2) {
|
||||
>required1 ?? required2 : () => boolean
|
||||
>required1 : () => boolean
|
||||
>required2 : () => boolean
|
||||
}
|
||||
|
||||
// error
|
||||
if (((required1 && b))) {
|
||||
>((required1 && b)) : boolean
|
||||
@ -174,6 +202,39 @@ function test(required1: () => boolean, required2: () => boolean, b: boolean, op
|
||||
>required1 : () => boolean
|
||||
}
|
||||
|
||||
// ok
|
||||
if (required1 || b) {
|
||||
>required1 || b : () => boolean
|
||||
>required1 : () => boolean
|
||||
>b : boolean
|
||||
|
||||
required1();
|
||||
>required1() : boolean
|
||||
>required1 : () => boolean
|
||||
}
|
||||
|
||||
// ok
|
||||
if (required1 ?? b) {
|
||||
>required1 ?? b : () => boolean
|
||||
>required1 : () => boolean
|
||||
>b : boolean
|
||||
|
||||
required1();
|
||||
>required1() : boolean
|
||||
>required1 : () => boolean
|
||||
}
|
||||
|
||||
// ok
|
||||
if (b ?? required1) {
|
||||
>b ?? required1 : boolean
|
||||
>b : boolean
|
||||
>required1 : () => boolean
|
||||
|
||||
required1();
|
||||
>required1() : boolean
|
||||
>required1 : () => boolean
|
||||
}
|
||||
|
||||
// ok
|
||||
if (((required1 && b))) {
|
||||
>((required1 && b)) : boolean
|
||||
@ -186,6 +247,52 @@ function test(required1: () => boolean, required2: () => boolean, b: boolean, op
|
||||
>required1() : boolean
|
||||
>required1 : () => boolean
|
||||
}
|
||||
|
||||
// error, extra parens are on purpose here
|
||||
if ((required1)) {
|
||||
>(required1) : () => boolean
|
||||
>required1 : () => boolean
|
||||
}
|
||||
|
||||
// error
|
||||
if (b && (required1 || required2)) {
|
||||
>b && (required1 || required2) : false | (() => boolean)
|
||||
>b : boolean
|
||||
>(required1 || required2) : () => boolean
|
||||
>required1 || required2 : () => boolean
|
||||
>required1 : () => boolean
|
||||
>required2 : () => boolean
|
||||
}
|
||||
|
||||
// error
|
||||
if ((required1 || required2) && b) {
|
||||
>(required1 || required2) && b : boolean
|
||||
>(required1 || required2) : () => boolean
|
||||
>required1 || required2 : () => boolean
|
||||
>required1 : () => boolean
|
||||
>required2 : () => boolean
|
||||
>b : boolean
|
||||
}
|
||||
|
||||
// error
|
||||
if (b && (required1 ?? required2)) {
|
||||
>b && (required1 ?? required2) : false | (() => boolean)
|
||||
>b : boolean
|
||||
>(required1 ?? required2) : () => boolean
|
||||
>required1 ?? required2 : () => boolean
|
||||
>required1 : () => boolean
|
||||
>required2 : () => boolean
|
||||
}
|
||||
|
||||
// error
|
||||
if ((required1 ?? required2) && b) {
|
||||
>(required1 ?? required2) && b : boolean
|
||||
>(required1 ?? required2) : () => boolean
|
||||
>required1 ?? required2 : () => boolean
|
||||
>required1 : () => boolean
|
||||
>required2 : () => boolean
|
||||
>b : boolean
|
||||
}
|
||||
}
|
||||
|
||||
function checksConsole() {
|
||||
@ -372,6 +479,106 @@ function checksPropertyAccess() {
|
||||
>a : { b: { c: () => void; }; }
|
||||
>b : { c: () => void; }
|
||||
>c : () => void
|
||||
|
||||
// error, extra parens are on purpose here
|
||||
if ((x1.a.b.c)) {
|
||||
>(x1.a.b.c) : () => void
|
||||
>x1.a.b.c : () => void
|
||||
>x1.a.b : { c: () => void; }
|
||||
>x1.a : { b: { c: () => void; }; }
|
||||
>x1 : { a: { b: { c: () => void; }; }; }
|
||||
>a : { b: { c: () => void; }; }
|
||||
>b : { c: () => void; }
|
||||
>c : () => void
|
||||
}
|
||||
|
||||
// error
|
||||
if (1 && (x1.a.b.c || x2.a.b.c)) {
|
||||
>1 && (x1.a.b.c || x2.a.b.c) : () => void
|
||||
>1 : 1
|
||||
>(x1.a.b.c || x2.a.b.c) : () => void
|
||||
>x1.a.b.c || x2.a.b.c : () => void
|
||||
>x1.a.b.c : () => void
|
||||
>x1.a.b : { c: () => void; }
|
||||
>x1.a : { b: { c: () => void; }; }
|
||||
>x1 : { a: { b: { c: () => void; }; }; }
|
||||
>a : { b: { c: () => void; }; }
|
||||
>b : { c: () => void; }
|
||||
>c : () => void
|
||||
>x2.a.b.c : () => void
|
||||
>x2.a.b : { c: () => void; }
|
||||
>x2.a : { b: { c: () => void; }; }
|
||||
>x2 : { a: { b: { c: () => void; }; }; }
|
||||
>a : { b: { c: () => void; }; }
|
||||
>b : { c: () => void; }
|
||||
>c : () => void
|
||||
}
|
||||
|
||||
// error
|
||||
if ((x1.a.b.c || x2.a.b.c) && 1) {
|
||||
>(x1.a.b.c || x2.a.b.c) && 1 : 1
|
||||
>(x1.a.b.c || x2.a.b.c) : () => void
|
||||
>x1.a.b.c || x2.a.b.c : () => void
|
||||
>x1.a.b.c : () => void
|
||||
>x1.a.b : { c: () => void; }
|
||||
>x1.a : { b: { c: () => void; }; }
|
||||
>x1 : { a: { b: { c: () => void; }; }; }
|
||||
>a : { b: { c: () => void; }; }
|
||||
>b : { c: () => void; }
|
||||
>c : () => void
|
||||
>x2.a.b.c : () => void
|
||||
>x2.a.b : { c: () => void; }
|
||||
>x2.a : { b: { c: () => void; }; }
|
||||
>x2 : { a: { b: { c: () => void; }; }; }
|
||||
>a : { b: { c: () => void; }; }
|
||||
>b : { c: () => void; }
|
||||
>c : () => void
|
||||
>1 : 1
|
||||
}
|
||||
|
||||
// error
|
||||
if (1 && (x1.a.b.c ?? x2.a.b.c)) {
|
||||
>1 && (x1.a.b.c ?? x2.a.b.c) : () => void
|
||||
>1 : 1
|
||||
>(x1.a.b.c ?? x2.a.b.c) : () => void
|
||||
>x1.a.b.c ?? x2.a.b.c : () => void
|
||||
>x1.a.b.c : () => void
|
||||
>x1.a.b : { c: () => void; }
|
||||
>x1.a : { b: { c: () => void; }; }
|
||||
>x1 : { a: { b: { c: () => void; }; }; }
|
||||
>a : { b: { c: () => void; }; }
|
||||
>b : { c: () => void; }
|
||||
>c : () => void
|
||||
>x2.a.b.c : () => void
|
||||
>x2.a.b : { c: () => void; }
|
||||
>x2.a : { b: { c: () => void; }; }
|
||||
>x2 : { a: { b: { c: () => void; }; }; }
|
||||
>a : { b: { c: () => void; }; }
|
||||
>b : { c: () => void; }
|
||||
>c : () => void
|
||||
}
|
||||
|
||||
// error
|
||||
if ((x1.a.b.c ?? x2.a.b.c) && 1) {
|
||||
>(x1.a.b.c ?? x2.a.b.c) && 1 : 1
|
||||
>(x1.a.b.c ?? x2.a.b.c) : () => void
|
||||
>x1.a.b.c ?? x2.a.b.c : () => void
|
||||
>x1.a.b.c : () => void
|
||||
>x1.a.b : { c: () => void; }
|
||||
>x1.a : { b: { c: () => void; }; }
|
||||
>x1 : { a: { b: { c: () => void; }; }; }
|
||||
>a : { b: { c: () => void; }; }
|
||||
>b : { c: () => void; }
|
||||
>c : () => void
|
||||
>x2.a.b.c : () => void
|
||||
>x2.a.b : { c: () => void; }
|
||||
>x2.a : { b: { c: () => void; }; }
|
||||
>x2 : { a: { b: { c: () => void; }; }; }
|
||||
>a : { b: { c: () => void; }; }
|
||||
>b : { c: () => void; }
|
||||
>c : () => void
|
||||
>1 : 1
|
||||
}
|
||||
}
|
||||
|
||||
class Foo {
|
||||
|
||||
@ -1,8 +1,9 @@
|
||||
tests/cases/compiler/uncalledFunctionChecksInConditional2.ts(20,5): error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
|
||||
tests/cases/compiler/uncalledFunctionChecksInConditional2.ts(38,5): error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
|
||||
tests/cases/compiler/uncalledFunctionChecksInConditional2.ts(30,7): error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
|
||||
tests/cases/compiler/uncalledFunctionChecksInConditional2.ts(49,5): error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
|
||||
|
||||
|
||||
==== tests/cases/compiler/uncalledFunctionChecksInConditional2.ts (2 errors) ====
|
||||
==== tests/cases/compiler/uncalledFunctionChecksInConditional2.ts (3 errors) ====
|
||||
{
|
||||
const perf = window.performance
|
||||
|
||||
@ -28,6 +29,19 @@ tests/cases/compiler/uncalledFunctionChecksInConditional2.ts(38,5): error TS2774
|
||||
) {
|
||||
perf.mark("");
|
||||
}
|
||||
|
||||
// With ??
|
||||
if (
|
||||
(
|
||||
perf &&
|
||||
perf.mark &&
|
||||
perf.measure
|
||||
~~~~~~~~~~~~
|
||||
!!! error TS2774: This condition will always return true since this function is always defined. Did you mean to call it instead?
|
||||
) ?? !!true
|
||||
) {
|
||||
perf.mark("");
|
||||
}
|
||||
};
|
||||
|
||||
// Original #49192
|
||||
|
||||
@ -22,6 +22,17 @@
|
||||
) {
|
||||
perf.mark("");
|
||||
}
|
||||
|
||||
// With ??
|
||||
if (
|
||||
(
|
||||
perf &&
|
||||
perf.mark &&
|
||||
perf.measure
|
||||
) ?? !!true
|
||||
) {
|
||||
perf.mark("");
|
||||
}
|
||||
};
|
||||
|
||||
// Original #49192
|
||||
@ -50,6 +61,7 @@ declare let inBrowser: boolean;
|
||||
|
||||
|
||||
//// [uncalledFunctionChecksInConditional2.js]
|
||||
var _a;
|
||||
{
|
||||
var perf = window.performance;
|
||||
// Simplified
|
||||
@ -67,6 +79,12 @@ declare let inBrowser: boolean;
|
||||
perf.measure || !!true) {
|
||||
perf.mark("");
|
||||
}
|
||||
// With ??
|
||||
if ((_a = (perf &&
|
||||
perf.mark &&
|
||||
perf.measure)) !== null && _a !== void 0 ? _a : !!true) {
|
||||
perf.mark("");
|
||||
}
|
||||
}
|
||||
;
|
||||
{
|
||||
|
||||
@ -62,23 +62,47 @@
|
||||
perf.mark("");
|
||||
>perf.mark : Symbol(Performance.mark, Decl(lib.dom.d.ts, --, --))
|
||||
>perf : Symbol(perf, Decl(uncalledFunctionChecksInConditional2.ts, 1, 7))
|
||||
>mark : Symbol(Performance.mark, Decl(lib.dom.d.ts, --, --))
|
||||
}
|
||||
|
||||
// With ??
|
||||
if (
|
||||
(
|
||||
perf &&
|
||||
>perf : Symbol(perf, Decl(uncalledFunctionChecksInConditional2.ts, 1, 7))
|
||||
|
||||
perf.mark &&
|
||||
>perf.mark : Symbol(Performance.mark, Decl(lib.dom.d.ts, --, --))
|
||||
>perf : Symbol(perf, Decl(uncalledFunctionChecksInConditional2.ts, 1, 7))
|
||||
>mark : Symbol(Performance.mark, Decl(lib.dom.d.ts, --, --))
|
||||
|
||||
perf.measure
|
||||
>perf.measure : Symbol(Performance.measure, Decl(lib.dom.d.ts, --, --))
|
||||
>perf : Symbol(perf, Decl(uncalledFunctionChecksInConditional2.ts, 1, 7))
|
||||
>measure : Symbol(Performance.measure, Decl(lib.dom.d.ts, --, --))
|
||||
|
||||
) ?? !!true
|
||||
) {
|
||||
perf.mark("");
|
||||
>perf.mark : Symbol(Performance.mark, Decl(lib.dom.d.ts, --, --))
|
||||
>perf : Symbol(perf, Decl(uncalledFunctionChecksInConditional2.ts, 1, 7))
|
||||
>mark : Symbol(Performance.mark, Decl(lib.dom.d.ts, --, --))
|
||||
}
|
||||
};
|
||||
|
||||
// Original #49192
|
||||
declare let inBrowser: boolean;
|
||||
>inBrowser : Symbol(inBrowser, Decl(uncalledFunctionChecksInConditional2.ts, 26, 11))
|
||||
>inBrowser : Symbol(inBrowser, Decl(uncalledFunctionChecksInConditional2.ts, 37, 11))
|
||||
{
|
||||
let mark;
|
||||
>mark : Symbol(mark, Decl(uncalledFunctionChecksInConditional2.ts, 28, 5))
|
||||
>mark : Symbol(mark, Decl(uncalledFunctionChecksInConditional2.ts, 39, 5))
|
||||
|
||||
let measure;
|
||||
>measure : Symbol(measure, Decl(uncalledFunctionChecksInConditional2.ts, 29, 5))
|
||||
>measure : Symbol(measure, Decl(uncalledFunctionChecksInConditional2.ts, 40, 5))
|
||||
|
||||
const perf = inBrowser && window.performance
|
||||
>perf : Symbol(perf, Decl(uncalledFunctionChecksInConditional2.ts, 30, 7))
|
||||
>inBrowser : Symbol(inBrowser, Decl(uncalledFunctionChecksInConditional2.ts, 26, 11))
|
||||
>perf : Symbol(perf, Decl(uncalledFunctionChecksInConditional2.ts, 41, 7))
|
||||
>inBrowser : Symbol(inBrowser, Decl(uncalledFunctionChecksInConditional2.ts, 37, 11))
|
||||
>window.performance : Symbol(performance, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --))
|
||||
>window : Symbol(window, Decl(lib.dom.d.ts, --, --))
|
||||
>performance : Symbol(performance, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --))
|
||||
@ -86,62 +110,62 @@ declare let inBrowser: boolean;
|
||||
/* istanbul ignore if */
|
||||
if (
|
||||
perf &&
|
||||
>perf : Symbol(perf, Decl(uncalledFunctionChecksInConditional2.ts, 30, 7))
|
||||
>perf : Symbol(perf, Decl(uncalledFunctionChecksInConditional2.ts, 41, 7))
|
||||
|
||||
perf.mark &&
|
||||
>perf.mark : Symbol(Performance.mark, Decl(lib.dom.d.ts, --, --))
|
||||
>perf : Symbol(perf, Decl(uncalledFunctionChecksInConditional2.ts, 30, 7))
|
||||
>perf : Symbol(perf, Decl(uncalledFunctionChecksInConditional2.ts, 41, 7))
|
||||
>mark : Symbol(Performance.mark, Decl(lib.dom.d.ts, --, --))
|
||||
|
||||
perf.measure &&
|
||||
>perf.measure : Symbol(Performance.measure, Decl(lib.dom.d.ts, --, --))
|
||||
>perf : Symbol(perf, Decl(uncalledFunctionChecksInConditional2.ts, 30, 7))
|
||||
>perf : Symbol(perf, Decl(uncalledFunctionChecksInConditional2.ts, 41, 7))
|
||||
>measure : Symbol(Performance.measure, Decl(lib.dom.d.ts, --, --))
|
||||
|
||||
perf.clearMarks &&
|
||||
>perf.clearMarks : Symbol(Performance.clearMarks, Decl(lib.dom.d.ts, --, --))
|
||||
>perf : Symbol(perf, Decl(uncalledFunctionChecksInConditional2.ts, 30, 7))
|
||||
>perf : Symbol(perf, Decl(uncalledFunctionChecksInConditional2.ts, 41, 7))
|
||||
>clearMarks : Symbol(Performance.clearMarks, Decl(lib.dom.d.ts, --, --))
|
||||
|
||||
perf.clearMeasures
|
||||
>perf.clearMeasures : Symbol(Performance.clearMeasures, Decl(lib.dom.d.ts, --, --))
|
||||
>perf : Symbol(perf, Decl(uncalledFunctionChecksInConditional2.ts, 30, 7))
|
||||
>perf : Symbol(perf, Decl(uncalledFunctionChecksInConditional2.ts, 41, 7))
|
||||
>clearMeasures : Symbol(Performance.clearMeasures, Decl(lib.dom.d.ts, --, --))
|
||||
|
||||
) {
|
||||
mark = (tag) => perf.mark(tag)
|
||||
>mark : Symbol(mark, Decl(uncalledFunctionChecksInConditional2.ts, 28, 5))
|
||||
>tag : Symbol(tag, Decl(uncalledFunctionChecksInConditional2.ts, 39, 12))
|
||||
>mark : Symbol(mark, Decl(uncalledFunctionChecksInConditional2.ts, 39, 5))
|
||||
>tag : Symbol(tag, Decl(uncalledFunctionChecksInConditional2.ts, 50, 12))
|
||||
>perf.mark : Symbol(Performance.mark, Decl(lib.dom.d.ts, --, --))
|
||||
>perf : Symbol(perf, Decl(uncalledFunctionChecksInConditional2.ts, 30, 7))
|
||||
>perf : Symbol(perf, Decl(uncalledFunctionChecksInConditional2.ts, 41, 7))
|
||||
>mark : Symbol(Performance.mark, Decl(lib.dom.d.ts, --, --))
|
||||
>tag : Symbol(tag, Decl(uncalledFunctionChecksInConditional2.ts, 39, 12))
|
||||
>tag : Symbol(tag, Decl(uncalledFunctionChecksInConditional2.ts, 50, 12))
|
||||
|
||||
measure = (name, startTag, endTag) => {
|
||||
>measure : Symbol(measure, Decl(uncalledFunctionChecksInConditional2.ts, 29, 5))
|
||||
>name : Symbol(name, Decl(uncalledFunctionChecksInConditional2.ts, 40, 15))
|
||||
>startTag : Symbol(startTag, Decl(uncalledFunctionChecksInConditional2.ts, 40, 20))
|
||||
>endTag : Symbol(endTag, Decl(uncalledFunctionChecksInConditional2.ts, 40, 30))
|
||||
>measure : Symbol(measure, Decl(uncalledFunctionChecksInConditional2.ts, 40, 5))
|
||||
>name : Symbol(name, Decl(uncalledFunctionChecksInConditional2.ts, 51, 15))
|
||||
>startTag : Symbol(startTag, Decl(uncalledFunctionChecksInConditional2.ts, 51, 20))
|
||||
>endTag : Symbol(endTag, Decl(uncalledFunctionChecksInConditional2.ts, 51, 30))
|
||||
|
||||
perf.measure(name, startTag, endTag)
|
||||
>perf.measure : Symbol(Performance.measure, Decl(lib.dom.d.ts, --, --))
|
||||
>perf : Symbol(perf, Decl(uncalledFunctionChecksInConditional2.ts, 30, 7))
|
||||
>perf : Symbol(perf, Decl(uncalledFunctionChecksInConditional2.ts, 41, 7))
|
||||
>measure : Symbol(Performance.measure, Decl(lib.dom.d.ts, --, --))
|
||||
>name : Symbol(name, Decl(uncalledFunctionChecksInConditional2.ts, 40, 15))
|
||||
>startTag : Symbol(startTag, Decl(uncalledFunctionChecksInConditional2.ts, 40, 20))
|
||||
>endTag : Symbol(endTag, Decl(uncalledFunctionChecksInConditional2.ts, 40, 30))
|
||||
>name : Symbol(name, Decl(uncalledFunctionChecksInConditional2.ts, 51, 15))
|
||||
>startTag : Symbol(startTag, Decl(uncalledFunctionChecksInConditional2.ts, 51, 20))
|
||||
>endTag : Symbol(endTag, Decl(uncalledFunctionChecksInConditional2.ts, 51, 30))
|
||||
|
||||
perf.clearMarks(startTag)
|
||||
>perf.clearMarks : Symbol(Performance.clearMarks, Decl(lib.dom.d.ts, --, --))
|
||||
>perf : Symbol(perf, Decl(uncalledFunctionChecksInConditional2.ts, 30, 7))
|
||||
>perf : Symbol(perf, Decl(uncalledFunctionChecksInConditional2.ts, 41, 7))
|
||||
>clearMarks : Symbol(Performance.clearMarks, Decl(lib.dom.d.ts, --, --))
|
||||
>startTag : Symbol(startTag, Decl(uncalledFunctionChecksInConditional2.ts, 40, 20))
|
||||
>startTag : Symbol(startTag, Decl(uncalledFunctionChecksInConditional2.ts, 51, 20))
|
||||
|
||||
perf.clearMarks(endTag)
|
||||
>perf.clearMarks : Symbol(Performance.clearMarks, Decl(lib.dom.d.ts, --, --))
|
||||
>perf : Symbol(perf, Decl(uncalledFunctionChecksInConditional2.ts, 30, 7))
|
||||
>perf : Symbol(perf, Decl(uncalledFunctionChecksInConditional2.ts, 41, 7))
|
||||
>clearMarks : Symbol(Performance.clearMarks, Decl(lib.dom.d.ts, --, --))
|
||||
>endTag : Symbol(endTag, Decl(uncalledFunctionChecksInConditional2.ts, 40, 30))
|
||||
>endTag : Symbol(endTag, Decl(uncalledFunctionChecksInConditional2.ts, 51, 30))
|
||||
|
||||
// perf.clearMeasures(name)
|
||||
}
|
||||
|
||||
@ -79,6 +79,41 @@
|
||||
>perf.mark : (markName: string, markOptions?: PerformanceMarkOptions | undefined) => PerformanceMark
|
||||
>perf : Performance
|
||||
>mark : (markName: string, markOptions?: PerformanceMarkOptions | undefined) => PerformanceMark
|
||||
>"" : ""
|
||||
}
|
||||
|
||||
// With ??
|
||||
if (
|
||||
(
|
||||
>( perf && perf.mark && perf.measure ) ?? !!true : (measureName: string, startOrMeasureOptions?: string | PerformanceMeasureOptions | undefined, endMark?: string | undefined) => PerformanceMeasure
|
||||
>( perf && perf.mark && perf.measure ) : (measureName: string, startOrMeasureOptions?: string | PerformanceMeasureOptions | undefined, endMark?: string | undefined) => PerformanceMeasure
|
||||
|
||||
perf &&
|
||||
>perf && perf.mark && perf.measure : (measureName: string, startOrMeasureOptions?: string | PerformanceMeasureOptions | undefined, endMark?: string | undefined) => PerformanceMeasure
|
||||
>perf && perf.mark : (markName: string, markOptions?: PerformanceMarkOptions | undefined) => PerformanceMark
|
||||
>perf : Performance
|
||||
|
||||
perf.mark &&
|
||||
>perf.mark : (markName: string, markOptions?: PerformanceMarkOptions | undefined) => PerformanceMark
|
||||
>perf : Performance
|
||||
>mark : (markName: string, markOptions?: PerformanceMarkOptions | undefined) => PerformanceMark
|
||||
|
||||
perf.measure
|
||||
>perf.measure : (measureName: string, startOrMeasureOptions?: string | PerformanceMeasureOptions | undefined, endMark?: string | undefined) => PerformanceMeasure
|
||||
>perf : Performance
|
||||
>measure : (measureName: string, startOrMeasureOptions?: string | PerformanceMeasureOptions | undefined, endMark?: string | undefined) => PerformanceMeasure
|
||||
|
||||
) ?? !!true
|
||||
>!!true : true
|
||||
>!true : false
|
||||
>true : true
|
||||
|
||||
) {
|
||||
perf.mark("");
|
||||
>perf.mark("") : PerformanceMark
|
||||
>perf.mark : (markName: string, markOptions?: PerformanceMarkOptions | undefined) => PerformanceMark
|
||||
>perf : Performance
|
||||
>mark : (markName: string, markOptions?: PerformanceMarkOptions | undefined) => PerformanceMark
|
||||
>"" : ""
|
||||
}
|
||||
};
|
||||
|
||||
@ -47,6 +47,22 @@ function test(required1: () => boolean, required2: () => boolean, b: boolean, op
|
||||
if (required1 && b) {
|
||||
}
|
||||
|
||||
// error
|
||||
if (required1 || b) {
|
||||
}
|
||||
|
||||
// error
|
||||
if (required1 || required2) {
|
||||
}
|
||||
|
||||
// error
|
||||
if (required1 ?? b) {
|
||||
}
|
||||
|
||||
// error
|
||||
if (required1 ?? required2) {
|
||||
}
|
||||
|
||||
// error
|
||||
if (((required1 && b))) {
|
||||
}
|
||||
@ -56,10 +72,45 @@ function test(required1: () => boolean, required2: () => boolean, b: boolean, op
|
||||
required1();
|
||||
}
|
||||
|
||||
// ok
|
||||
if (required1 || b) {
|
||||
required1();
|
||||
}
|
||||
|
||||
// ok
|
||||
if (required1 ?? b) {
|
||||
required1();
|
||||
}
|
||||
|
||||
// ok
|
||||
if (b ?? required1) {
|
||||
required1();
|
||||
}
|
||||
|
||||
// ok
|
||||
if (((required1 && b))) {
|
||||
required1();
|
||||
}
|
||||
|
||||
// error, extra parens are on purpose here
|
||||
if ((required1)) {
|
||||
}
|
||||
|
||||
// error
|
||||
if (b && (required1 || required2)) {
|
||||
}
|
||||
|
||||
// error
|
||||
if ((required1 || required2) && b) {
|
||||
}
|
||||
|
||||
// error
|
||||
if (b && (required1 ?? required2)) {
|
||||
}
|
||||
|
||||
// error
|
||||
if ((required1 ?? required2) && b) {
|
||||
}
|
||||
}
|
||||
|
||||
function checksConsole() {
|
||||
@ -100,6 +151,26 @@ function checksPropertyAccess() {
|
||||
|
||||
// error
|
||||
x1.a.b.c && x2.a.b.c();
|
||||
|
||||
// error, extra parens are on purpose here
|
||||
if ((x1.a.b.c)) {
|
||||
}
|
||||
|
||||
// error
|
||||
if (1 && (x1.a.b.c || x2.a.b.c)) {
|
||||
}
|
||||
|
||||
// error
|
||||
if ((x1.a.b.c || x2.a.b.c) && 1) {
|
||||
}
|
||||
|
||||
// error
|
||||
if (1 && (x1.a.b.c ?? x2.a.b.c)) {
|
||||
}
|
||||
|
||||
// error
|
||||
if ((x1.a.b.c ?? x2.a.b.c) && 1) {
|
||||
}
|
||||
}
|
||||
|
||||
class Foo {
|
||||
|
||||
@ -23,6 +23,17 @@
|
||||
) {
|
||||
perf.mark("");
|
||||
}
|
||||
|
||||
// With ??
|
||||
if (
|
||||
(
|
||||
perf &&
|
||||
perf.mark &&
|
||||
perf.measure
|
||||
) ?? !!true
|
||||
) {
|
||||
perf.mark("");
|
||||
}
|
||||
};
|
||||
|
||||
// Original #49192
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user