Skip to content

Commit 04266aa

Browse files
authored
narrowTypeByInstanceof understands ctor funcs (microsoft#27551)
* narrowTypeByInstanceof understands ctor funcs * Rename test filename * Fix whitespace lint
1 parent f074049 commit 04266aa

File tree

5 files changed

+73
-199
lines changed

5 files changed

+73
-199
lines changed

src/compiler/checker.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15391,9 +15391,12 @@ namespace ts {
1539115391
}
1539215392

1539315393
if (!targetType) {
15394-
const constructSignatures = getSignaturesOfType(rightType, SignatureKind.Construct);
15395-
targetType = constructSignatures && constructSignatures.length ?
15396-
getUnionType(map(constructSignatures, signature => getReturnTypeOfSignature(getErasedSignature(signature)))) :
15394+
let constructSignatures = getSignaturesOfType(rightType, SignatureKind.Construct);
15395+
if (constructSignatures.length === 0) {
15396+
constructSignatures = filter(getSignaturesOfType(rightType, SignatureKind.Call), sig => isJSConstructor(sig.declaration));
15397+
}
15398+
targetType = constructSignatures.length ?
15399+
getUnionType(map(constructSignatures, signature => isJSConstructor(signature.declaration) && getJSClassType(getSymbolOfNode(signature.declaration!)) || getReturnTypeOfSignature(getErasedSignature(signature)))) :
1539715400
emptyObjectType;
1539815401
}
1539915402

tests/baselines/reference/controlFlowInstanceof.js

Lines changed: 0 additions & 196 deletions
This file was deleted.

tests/baselines/reference/controlFlowInstanceof.symbols

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,3 +247,28 @@ if (x instanceof ctor) {
247247
>x : Symbol(x, Decl(controlFlowInstanceof.ts, 100, 13))
248248
}
249249

250+
// Repro from #27550 (based on uglify code)
251+
=== tests/cases/compiler/uglify.js ===
252+
/** @constructor */
253+
function AtTop(val) { this.val = val }
254+
>AtTop : Symbol(AtTop, Decl(uglify.js, 0, 0))
255+
>val : Symbol(val, Decl(uglify.js, 1, 15))
256+
>this.val : Symbol(AtTop.val, Decl(uglify.js, 1, 21))
257+
>this : Symbol(AtTop, Decl(uglify.js, 0, 0))
258+
>val : Symbol(AtTop.val, Decl(uglify.js, 1, 21))
259+
>val : Symbol(val, Decl(uglify.js, 1, 15))
260+
261+
/** @type {*} */
262+
var v = 1;
263+
>v : Symbol(v, Decl(uglify.js, 3, 3))
264+
265+
if (v instanceof AtTop) {
266+
>v : Symbol(v, Decl(uglify.js, 3, 3))
267+
>AtTop : Symbol(AtTop, Decl(uglify.js, 0, 0))
268+
269+
v.val
270+
>v.val : Symbol(AtTop.val, Decl(uglify.js, 1, 21))
271+
>v : Symbol(v, Decl(uglify.js, 3, 3))
272+
>val : Symbol(AtTop.val, Decl(uglify.js, 1, 21))
273+
}
274+

tests/baselines/reference/controlFlowInstanceof.types

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,3 +261,31 @@ if (x instanceof ctor) {
261261
>x : () => void
262262
}
263263

264+
// Repro from #27550 (based on uglify code)
265+
=== tests/cases/compiler/uglify.js ===
266+
/** @constructor */
267+
function AtTop(val) { this.val = val }
268+
>AtTop : typeof AtTop
269+
>val : any
270+
>this.val = val : any
271+
>this.val : any
272+
>this : AtTop
273+
>val : any
274+
>val : any
275+
276+
/** @type {*} */
277+
var v = 1;
278+
>v : any
279+
>1 : 1
280+
281+
if (v instanceof AtTop) {
282+
>v instanceof AtTop : boolean
283+
>v : any
284+
>AtTop : typeof AtTop
285+
286+
v.val
287+
>v.val : any
288+
>v : AtTop
289+
>val : any
290+
}
291+

tests/cases/compiler/controlFlowInstanceof.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
// @target: es6
2+
// @noEmit: true
3+
// @allowJs: true
4+
// @checkJs: true
25
// @strictNullChecks: true
36

7+
// @Filename: controlFlowInstanceof.ts
48
// Repros from #10167
59

610
function f1(s: Set<string> | Set<number>) {
@@ -107,3 +111,13 @@ declare const ctor: Function;
107111
if (x instanceof ctor) {
108112
x();
109113
}
114+
115+
// Repro from #27550 (based on uglify code)
116+
// @Filename: uglify.js
117+
/** @constructor */
118+
function AtTop(val) { this.val = val }
119+
/** @type {*} */
120+
var v = 1;
121+
if (v instanceof AtTop) {
122+
v.val
123+
}

0 commit comments

Comments
 (0)