Skip to content

Commit 81f8b47

Browse files
authored
Merge pull request microsoft#27370 from Microsoft/fixInstanceOfFunction
Fix instanceof with type Function for right argument
2 parents 9851d6f + 735f166 commit 81f8b47

File tree

5 files changed

+78
-28
lines changed

5 files changed

+78
-28
lines changed

src/compiler/checker.ts

+5-16
Original file line numberDiff line numberDiff line change
@@ -15391,24 +15391,13 @@ namespace ts {
1539115391
}
1539215392

1539315393
if (!targetType) {
15394-
// Target type is type of construct signature
15395-
let constructSignatures: ReadonlyArray<Signature> | undefined;
15396-
if (getObjectFlags(rightType) & ObjectFlags.Interface) {
15397-
constructSignatures = resolveDeclaredMembers(<InterfaceType>rightType).declaredConstructSignatures;
15398-
}
15399-
else if (getObjectFlags(rightType) & ObjectFlags.Anonymous) {
15400-
constructSignatures = getSignaturesOfType(rightType, SignatureKind.Construct);
15401-
}
15402-
if (constructSignatures && constructSignatures.length) {
15403-
targetType = getUnionType(map(constructSignatures, signature => getReturnTypeOfSignature(getErasedSignature(signature))));
15404-
}
15394+
const constructSignatures = getSignaturesOfType(rightType, SignatureKind.Construct);
15395+
targetType = constructSignatures && constructSignatures.length ?
15396+
getUnionType(map(constructSignatures, signature => getReturnTypeOfSignature(getErasedSignature(signature)))) :
15397+
emptyObjectType;
1540515398
}
1540615399

15407-
if (targetType) {
15408-
return getNarrowedType(type, targetType, assumeTrue, isTypeDerivedFrom);
15409-
}
15410-
15411-
return type;
15400+
return getNarrowedType(type, targetType, assumeTrue, isTypeDerivedFrom);
1541215401
}
1541315402

1541415403
function getNarrowedType(type: Type, candidate: Type, assumeTrue: boolean, isRelated: (source: Type, target: Type) => boolean) {

tests/baselines/reference/controlFlowInstanceof.js

+14-1
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,17 @@ function goo(x: X) {
9595
x.y;
9696
}
9797
x;
98-
}
98+
}
99+
100+
// Repro from #27282
101+
102+
declare const x: (() => void)|null;
103+
declare const ctor: Function;
104+
105+
if (x instanceof ctor) {
106+
x();
107+
}
108+
99109

100110
//// [controlFlowInstanceof.js]
101111
// Repros from #10167
@@ -181,3 +191,6 @@ function goo(x) {
181191
}
182192
x;
183193
}
194+
if (x instanceof ctor) {
195+
x();
196+
}

tests/baselines/reference/controlFlowInstanceof.symbols

+18
Original file line numberDiff line numberDiff line change
@@ -229,3 +229,21 @@ function goo(x: X) {
229229
x;
230230
>x : Symbol(x, Decl(controlFlowInstanceof.ts, 90, 13))
231231
}
232+
233+
// Repro from #27282
234+
235+
declare const x: (() => void)|null;
236+
>x : Symbol(x, Decl(controlFlowInstanceof.ts, 100, 13))
237+
238+
declare const ctor: Function;
239+
>ctor : Symbol(ctor, Decl(controlFlowInstanceof.ts, 101, 13))
240+
>Function : Symbol(Function, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --))
241+
242+
if (x instanceof ctor) {
243+
>x : Symbol(x, Decl(controlFlowInstanceof.ts, 100, 13))
244+
>ctor : Symbol(ctor, Decl(controlFlowInstanceof.ts, 101, 13))
245+
246+
x();
247+
>x : Symbol(x, Decl(controlFlowInstanceof.ts, 100, 13))
248+
}
249+

tests/baselines/reference/controlFlowInstanceof.types

+30-10
Original file line numberDiff line numberDiff line change
@@ -130,31 +130,31 @@ class C extends A { c: string }
130130
>c : string
131131

132132
function foo(x: A | undefined) {
133-
>foo : (x: A) => void
134-
>x : A
133+
>foo : (x: A | undefined) => void
134+
>x : A | undefined
135135

136136
x; // A | undefined
137-
>x : A
137+
>x : A | undefined
138138

139139
if (x instanceof B || x instanceof C) {
140140
>x instanceof B || x instanceof C : boolean
141141
>x instanceof B : boolean
142-
>x : A
142+
>x : A | undefined
143143
>B : typeof B
144144
>x instanceof C : boolean
145-
>x : A
145+
>x : A | undefined
146146
>C : typeof C
147147

148148
x; // B | C
149149
>x : B | C
150150
}
151151
x; // A | undefined
152-
>x : A
152+
>x : A | undefined
153153

154154
if (x instanceof B && x instanceof C) {
155155
>x instanceof B && x instanceof C : boolean
156156
>x instanceof B : boolean
157-
>x : A
157+
>x : A | undefined
158158
>B : typeof B
159159
>x instanceof C : boolean
160160
>x : B
@@ -164,11 +164,11 @@ function foo(x: A | undefined) {
164164
>x : B & C
165165
}
166166
x; // A | undefined
167-
>x : A
167+
>x : A | undefined
168168

169169
if (!x) {
170170
>!x : boolean
171-
>x : A
171+
>x : A | undefined
172172

173173
return;
174174
}
@@ -211,7 +211,7 @@ function foo(x: A | undefined) {
211211

212212
interface X {
213213
x?: string;
214-
>x : string
214+
>x : string | undefined
215215
}
216216

217217
class Y {
@@ -241,3 +241,23 @@ function goo(x: X) {
241241
x;
242242
>x : X
243243
}
244+
245+
// Repro from #27282
246+
247+
declare const x: (() => void)|null;
248+
>x : (() => void) | null
249+
>null : null
250+
251+
declare const ctor: Function;
252+
>ctor : Function
253+
254+
if (x instanceof ctor) {
255+
>x instanceof ctor : boolean
256+
>x : (() => void) | null
257+
>ctor : Function
258+
259+
x();
260+
>x() : void
261+
>x : () => void
262+
}
263+

tests/cases/compiler/controlFlowInstanceof.ts

+11-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// @target: es6
2+
// @strictNullChecks: true
23

34
// Repros from #10167
45

@@ -96,4 +97,13 @@ function goo(x: X) {
9697
x.y;
9798
}
9899
x;
99-
}
100+
}
101+
102+
// Repro from #27282
103+
104+
declare const x: (() => void)|null;
105+
declare const ctor: Function;
106+
107+
if (x instanceof ctor) {
108+
x();
109+
}

0 commit comments

Comments
 (0)