Skip to content

Commit

Permalink
Cherry-pick PR #42626 into release-4.2 (#42780)
Browse files Browse the repository at this point in the history
Component commits:
214ef0c No did-you-mean-to-call error on casts
I chose to do the ad-hoc check rather than yet another tree walk.

1. It's faster to run and easier to read.
2. This error came from looking at real code. It happened twice, so I
think the best estimate for other uses that happened zero times is in
fact zero.
3. I couldn't think of other places to put the cast, given the
restrictions on `testedNode` just before the new code.

1d34778 Merge branch 'master' into no-did-you-mean-to-call-error-on-casts

Co-authored-by: Nathan Shively-Sanders <nathansa@microsoft.com>
  • Loading branch information
typescript-bot and sandersn committed Feb 16, 2021
1 parent 980b273 commit 7f64b3a
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 1 deletion.
5 changes: 4 additions & 1 deletion src/compiler/checker.ts
Expand Up @@ -34542,8 +34542,11 @@ namespace ts {
: isPropertyAccessExpression(location) ? location.name
: isBinaryExpression(location) && isIdentifier(location.right) ? location.right
: undefined;
const isPropertyExpressionCast = isPropertyAccessExpression(location)
&& isParenthesizedExpression(location.expression)
&& isAssertionExpression(location.expression.expression);

if (!testedNode) {
if (!testedNode || isPropertyExpressionCast) {
return;
}

Expand Down
19 changes: 19 additions & 0 deletions tests/baselines/reference/truthinessCallExpressionCoercion3.js
@@ -0,0 +1,19 @@
//// [truthinessCallExpressionCoercion3.ts]
// from #41640, based on an example in ant-design
interface I {
always(): void
}

function f(result: unknown) {
if ((result as I).always) {
return result
}
}


//// [truthinessCallExpressionCoercion3.js]
function f(result) {
if (result.always) {
return result;
}
}
@@ -0,0 +1,24 @@
=== tests/cases/compiler/truthinessCallExpressionCoercion3.ts ===
// from #41640, based on an example in ant-design
interface I {
>I : Symbol(I, Decl(truthinessCallExpressionCoercion3.ts, 0, 0))

always(): void
>always : Symbol(I.always, Decl(truthinessCallExpressionCoercion3.ts, 1, 13))
}

function f(result: unknown) {
>f : Symbol(f, Decl(truthinessCallExpressionCoercion3.ts, 3, 1))
>result : Symbol(result, Decl(truthinessCallExpressionCoercion3.ts, 5, 11))

if ((result as I).always) {
>(result as I).always : Symbol(I.always, Decl(truthinessCallExpressionCoercion3.ts, 1, 13))
>result : Symbol(result, Decl(truthinessCallExpressionCoercion3.ts, 5, 11))
>I : Symbol(I, Decl(truthinessCallExpressionCoercion3.ts, 0, 0))
>always : Symbol(I.always, Decl(truthinessCallExpressionCoercion3.ts, 1, 13))

return result
>result : Symbol(result, Decl(truthinessCallExpressionCoercion3.ts, 5, 11))
}
}

23 changes: 23 additions & 0 deletions tests/baselines/reference/truthinessCallExpressionCoercion3.types
@@ -0,0 +1,23 @@
=== tests/cases/compiler/truthinessCallExpressionCoercion3.ts ===
// from #41640, based on an example in ant-design
interface I {
always(): void
>always : () => void
}

function f(result: unknown) {
>f : (result: unknown) => unknown
>result : unknown

if ((result as I).always) {
>(result as I).always : () => void
>(result as I) : I
>result as I : I
>result : unknown
>always : () => void

return result
>result : unknown
}
}

13 changes: 13 additions & 0 deletions tests/cases/compiler/truthinessCallExpressionCoercion3.ts
@@ -0,0 +1,13 @@
// @strictNullChecks: true
// @lib: esnext,dom

// from #41640, based on an example in ant-design
interface I {
always(): void
}

function f(result: unknown) {
if ((result as I).always) {
return result
}
}

0 comments on commit 7f64b3a

Please sign in to comment.