Skip to content

Commit f133aed

Browse files
author
Nathan Fenner
committed
update narrowing tests for constrained children types
1 parent 52d81ce commit f133aed

File tree

5 files changed

+214
-90
lines changed

5 files changed

+214
-90
lines changed

src/compiler/checker.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16071,7 +16071,8 @@ namespace ts {
1607116071
);
1607216072

1607316073
// Infer the types from superType onto the return type of the child constructor.
16074-
inferTypes(inferenceContext.inferences, superType, getReturnTypeOfSignature(childConstructor), InferencePriority.ReturnType);
16074+
const childTemplateType = getReturnTypeOfSignature(childConstructor);
16075+
inferTypes(inferenceContext.inferences, superType, childTemplateType, InferencePriority.NakedTypeVariable);
1607516076

1607616077
// We extract the inferred arguments from the inference context.
1607716078
// silentNeverType indicates that no type could be inferred.
@@ -16080,7 +16081,7 @@ namespace ts {
1608016081

1608116082

1608216083
// Lastly, supply the childType with the new parameters.
16083-
return instantiateType(getReturnTypeOfSignature(childConstructor), param => {
16084+
return instantiateType(childTemplateType, param => {
1608416085
if (childTypeParameters.indexOf(param) >= 0) {
1608516086
return childArguments[childTypeParameters.indexOf(param)];
1608616087
}

tests/baselines/reference/narrowGenericTypeByInstanceOf.js

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -153,23 +153,38 @@ function exampleConstraints() {
153153
class Parent<A> {
154154
a: A;
155155
}
156-
class Child<B extends number> extends Parent<B> {
156+
class Child<B extends 1 | 2 | 3> extends Parent<B> {
157157
b: B;
158158
}
159159

160-
const objPass: Parent<number> = undefined as any;
160+
const objPass: Parent<1 | 2 | 3> = undefined as any;
161161
if (objPass instanceof Child) {
162-
objPass;
162+
objPass; // expect: Child<1 | 2 | 3>
163163
}
164164

165-
const objFour: Parent<4> = undefined as any;
166-
if (objFour instanceof Child) {
167-
objFour;
165+
const obj12: Parent<1 | 2> = undefined as any;
166+
if (obj12 instanceof Child) {
167+
obj12; // expect: Child<1 | 2>
168168
}
169169

170170
const objFail: Parent<string> = undefined as any;
171171
if (objFail instanceof Child) {
172-
objFail;
172+
objFail; // Child<any>, since string and 1|2|3 have no overlap.
173+
}
174+
175+
const objRefine: Parent<number> = undefined as any;
176+
if (objRefine instanceof Child) {
177+
objRefine; // expect: Child<1 | 2 | 3>
178+
}
179+
180+
const objRefine1234: Parent<1 | 2 | 3 | 4> = undefined as any;
181+
if (objRefine1234 instanceof Child) {
182+
objRefine1234; // expect: Child<1 | 2 | 3>
183+
}
184+
185+
const objOverlap: Parent<2 | 3 | 4 | 5> = undefined as any;
186+
if (objOverlap instanceof Child) {
187+
objOverlap; // ideally, Child<2 | 3>, but actually Child<any> since 2|3|4|5 is not a supertype of 1|2|3.
173188
}
174189
}
175190

@@ -391,15 +406,27 @@ function exampleConstraints() {
391406
}(Parent));
392407
var objPass = undefined;
393408
if (objPass instanceof Child) {
394-
objPass;
409+
objPass; // expect: Child<1 | 2 | 3>
395410
}
396-
var objFour = undefined;
397-
if (objFour instanceof Child) {
398-
objFour;
411+
var obj12 = undefined;
412+
if (obj12 instanceof Child) {
413+
obj12; // expect: Child<1 | 2>
399414
}
400415
var objFail = undefined;
401416
if (objFail instanceof Child) {
402-
objFail;
417+
objFail; // Child<any>, since string and 1|2|3 have no overlap.
418+
}
419+
var objRefine = undefined;
420+
if (objRefine instanceof Child) {
421+
objRefine; // expect: Child<1 | 2 | 3>
422+
}
423+
var objRefine1234 = undefined;
424+
if (objRefine1234 instanceof Child) {
425+
objRefine1234; // expect: Child<1 | 2 | 3>
426+
}
427+
var objOverlap = undefined;
428+
if (objOverlap instanceof Child) {
429+
objOverlap; // ideally, Child<2 | 3>, but actually Child<any> since 2|3|4|5 is not a supertype of 1|2|3.
403430
}
404431
}
405432
function exampleUnrelated() {

tests/baselines/reference/narrowGenericTypeByInstanceOf.symbols

Lines changed: 94 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -401,18 +401,18 @@ function exampleConstraints() {
401401
>a : Symbol(Parent.a, Decl(narrowGenericTypeByInstanceOf.ts, 151, 19))
402402
>A : Symbol(A, Decl(narrowGenericTypeByInstanceOf.ts, 151, 15))
403403
}
404-
class Child<B extends number> extends Parent<B> {
404+
class Child<B extends 1 | 2 | 3> extends Parent<B> {
405405
>Child : Symbol(Child, Decl(narrowGenericTypeByInstanceOf.ts, 153, 3))
406406
>B : Symbol(B, Decl(narrowGenericTypeByInstanceOf.ts, 154, 14))
407407
>Parent : Symbol(Parent, Decl(narrowGenericTypeByInstanceOf.ts, 150, 31))
408408
>B : Symbol(B, Decl(narrowGenericTypeByInstanceOf.ts, 154, 14))
409409

410410
b: B;
411-
>b : Symbol(Child.b, Decl(narrowGenericTypeByInstanceOf.ts, 154, 51))
411+
>b : Symbol(Child.b, Decl(narrowGenericTypeByInstanceOf.ts, 154, 54))
412412
>B : Symbol(B, Decl(narrowGenericTypeByInstanceOf.ts, 154, 14))
413413
}
414414

415-
const objPass: Parent<number> = undefined as any;
415+
const objPass: Parent<1 | 2 | 3> = undefined as any;
416416
>objPass : Symbol(objPass, Decl(narrowGenericTypeByInstanceOf.ts, 158, 7))
417417
>Parent : Symbol(Parent, Decl(narrowGenericTypeByInstanceOf.ts, 150, 31))
418418
>undefined : Symbol(undefined)
@@ -421,21 +421,21 @@ function exampleConstraints() {
421421
>objPass : Symbol(objPass, Decl(narrowGenericTypeByInstanceOf.ts, 158, 7))
422422
>Child : Symbol(Child, Decl(narrowGenericTypeByInstanceOf.ts, 153, 3))
423423

424-
objPass;
424+
objPass; // expect: Child<1 | 2 | 3>
425425
>objPass : Symbol(objPass, Decl(narrowGenericTypeByInstanceOf.ts, 158, 7))
426426
}
427427

428-
const objFour: Parent<4> = undefined as any;
429-
>objFour : Symbol(objFour, Decl(narrowGenericTypeByInstanceOf.ts, 163, 7))
428+
const obj12: Parent<1 | 2> = undefined as any;
429+
>obj12 : Symbol(obj12, Decl(narrowGenericTypeByInstanceOf.ts, 163, 7))
430430
>Parent : Symbol(Parent, Decl(narrowGenericTypeByInstanceOf.ts, 150, 31))
431431
>undefined : Symbol(undefined)
432432

433-
if (objFour instanceof Child) {
434-
>objFour : Symbol(objFour, Decl(narrowGenericTypeByInstanceOf.ts, 163, 7))
433+
if (obj12 instanceof Child) {
434+
>obj12 : Symbol(obj12, Decl(narrowGenericTypeByInstanceOf.ts, 163, 7))
435435
>Child : Symbol(Child, Decl(narrowGenericTypeByInstanceOf.ts, 153, 3))
436436

437-
objFour;
438-
>objFour : Symbol(objFour, Decl(narrowGenericTypeByInstanceOf.ts, 163, 7))
437+
obj12; // expect: Child<1 | 2>
438+
>obj12 : Symbol(obj12, Decl(narrowGenericTypeByInstanceOf.ts, 163, 7))
439439
}
440440

441441
const objFail: Parent<string> = undefined as any;
@@ -447,106 +447,145 @@ function exampleConstraints() {
447447
>objFail : Symbol(objFail, Decl(narrowGenericTypeByInstanceOf.ts, 168, 7))
448448
>Child : Symbol(Child, Decl(narrowGenericTypeByInstanceOf.ts, 153, 3))
449449

450-
objFail;
450+
objFail; // Child<any>, since string and 1|2|3 have no overlap.
451451
>objFail : Symbol(objFail, Decl(narrowGenericTypeByInstanceOf.ts, 168, 7))
452452
}
453+
454+
const objRefine: Parent<number> = undefined as any;
455+
>objRefine : Symbol(objRefine, Decl(narrowGenericTypeByInstanceOf.ts, 173, 7))
456+
>Parent : Symbol(Parent, Decl(narrowGenericTypeByInstanceOf.ts, 150, 31))
457+
>undefined : Symbol(undefined)
458+
459+
if (objRefine instanceof Child) {
460+
>objRefine : Symbol(objRefine, Decl(narrowGenericTypeByInstanceOf.ts, 173, 7))
461+
>Child : Symbol(Child, Decl(narrowGenericTypeByInstanceOf.ts, 153, 3))
462+
463+
objRefine; // expect: Child<1 | 2 | 3>
464+
>objRefine : Symbol(objRefine, Decl(narrowGenericTypeByInstanceOf.ts, 173, 7))
465+
}
466+
467+
const objRefine1234: Parent<1 | 2 | 3 | 4> = undefined as any;
468+
>objRefine1234 : Symbol(objRefine1234, Decl(narrowGenericTypeByInstanceOf.ts, 178, 7))
469+
>Parent : Symbol(Parent, Decl(narrowGenericTypeByInstanceOf.ts, 150, 31))
470+
>undefined : Symbol(undefined)
471+
472+
if (objRefine1234 instanceof Child) {
473+
>objRefine1234 : Symbol(objRefine1234, Decl(narrowGenericTypeByInstanceOf.ts, 178, 7))
474+
>Child : Symbol(Child, Decl(narrowGenericTypeByInstanceOf.ts, 153, 3))
475+
476+
objRefine1234; // expect: Child<1 | 2 | 3>
477+
>objRefine1234 : Symbol(objRefine1234, Decl(narrowGenericTypeByInstanceOf.ts, 178, 7))
478+
}
479+
480+
const objOverlap: Parent<2 | 3 | 4 | 5> = undefined as any;
481+
>objOverlap : Symbol(objOverlap, Decl(narrowGenericTypeByInstanceOf.ts, 183, 7))
482+
>Parent : Symbol(Parent, Decl(narrowGenericTypeByInstanceOf.ts, 150, 31))
483+
>undefined : Symbol(undefined)
484+
485+
if (objOverlap instanceof Child) {
486+
>objOverlap : Symbol(objOverlap, Decl(narrowGenericTypeByInstanceOf.ts, 183, 7))
487+
>Child : Symbol(Child, Decl(narrowGenericTypeByInstanceOf.ts, 153, 3))
488+
489+
objOverlap; // ideally, Child<2 | 3>, but actually Child<any> since 2|3|4|5 is not a supertype of 1|2|3.
490+
>objOverlap : Symbol(objOverlap, Decl(narrowGenericTypeByInstanceOf.ts, 183, 7))
491+
}
453492
}
454493

455494
function exampleUnrelated() {
456-
>exampleUnrelated : Symbol(exampleUnrelated, Decl(narrowGenericTypeByInstanceOf.ts, 172, 1))
495+
>exampleUnrelated : Symbol(exampleUnrelated, Decl(narrowGenericTypeByInstanceOf.ts, 187, 1))
457496

458497
class Child<A, B> {
459-
>Child : Symbol(Child, Decl(narrowGenericTypeByInstanceOf.ts, 174, 29))
460-
>A : Symbol(A, Decl(narrowGenericTypeByInstanceOf.ts, 175, 14))
461-
>B : Symbol(B, Decl(narrowGenericTypeByInstanceOf.ts, 175, 16))
498+
>Child : Symbol(Child, Decl(narrowGenericTypeByInstanceOf.ts, 189, 29))
499+
>A : Symbol(A, Decl(narrowGenericTypeByInstanceOf.ts, 190, 14))
500+
>B : Symbol(B, Decl(narrowGenericTypeByInstanceOf.ts, 190, 16))
462501

463502
a: A;
464-
>a : Symbol(Child.a, Decl(narrowGenericTypeByInstanceOf.ts, 175, 21))
465-
>A : Symbol(A, Decl(narrowGenericTypeByInstanceOf.ts, 175, 14))
503+
>a : Symbol(Child.a, Decl(narrowGenericTypeByInstanceOf.ts, 190, 21))
504+
>A : Symbol(A, Decl(narrowGenericTypeByInstanceOf.ts, 190, 14))
466505

467506
b: B;
468-
>b : Symbol(Child.b, Decl(narrowGenericTypeByInstanceOf.ts, 176, 9))
469-
>B : Symbol(B, Decl(narrowGenericTypeByInstanceOf.ts, 175, 16))
507+
>b : Symbol(Child.b, Decl(narrowGenericTypeByInstanceOf.ts, 191, 9))
508+
>B : Symbol(B, Decl(narrowGenericTypeByInstanceOf.ts, 190, 16))
470509

471510
foo: number;
472-
>foo : Symbol(Child.foo, Decl(narrowGenericTypeByInstanceOf.ts, 177, 9))
511+
>foo : Symbol(Child.foo, Decl(narrowGenericTypeByInstanceOf.ts, 192, 9))
473512
}
474513

475514
const objA = { a: 5 };
476-
>objA : Symbol(objA, Decl(narrowGenericTypeByInstanceOf.ts, 181, 7))
477-
>a : Symbol(a, Decl(narrowGenericTypeByInstanceOf.ts, 181, 16))
515+
>objA : Symbol(objA, Decl(narrowGenericTypeByInstanceOf.ts, 196, 7))
516+
>a : Symbol(a, Decl(narrowGenericTypeByInstanceOf.ts, 196, 16))
478517

479518
if (objA instanceof Child) {
480-
>objA : Symbol(objA, Decl(narrowGenericTypeByInstanceOf.ts, 181, 7))
481-
>Child : Symbol(Child, Decl(narrowGenericTypeByInstanceOf.ts, 174, 29))
519+
>objA : Symbol(objA, Decl(narrowGenericTypeByInstanceOf.ts, 196, 7))
520+
>Child : Symbol(Child, Decl(narrowGenericTypeByInstanceOf.ts, 189, 29))
482521

483522
objA; // Child<number, any>
484-
>objA : Symbol(objA, Decl(narrowGenericTypeByInstanceOf.ts, 181, 7))
523+
>objA : Symbol(objA, Decl(narrowGenericTypeByInstanceOf.ts, 196, 7))
485524
}
486525

487526
const objB = { b: "hello" };
488-
>objB : Symbol(objB, Decl(narrowGenericTypeByInstanceOf.ts, 186, 7))
489-
>b : Symbol(b, Decl(narrowGenericTypeByInstanceOf.ts, 186, 16))
527+
>objB : Symbol(objB, Decl(narrowGenericTypeByInstanceOf.ts, 201, 7))
528+
>b : Symbol(b, Decl(narrowGenericTypeByInstanceOf.ts, 201, 16))
490529

491530
if (objB instanceof Child) {
492-
>objB : Symbol(objB, Decl(narrowGenericTypeByInstanceOf.ts, 186, 7))
493-
>Child : Symbol(Child, Decl(narrowGenericTypeByInstanceOf.ts, 174, 29))
531+
>objB : Symbol(objB, Decl(narrowGenericTypeByInstanceOf.ts, 201, 7))
532+
>Child : Symbol(Child, Decl(narrowGenericTypeByInstanceOf.ts, 189, 29))
494533

495534
objB; // Child<any, string>
496-
>objB : Symbol(objB, Decl(narrowGenericTypeByInstanceOf.ts, 186, 7))
535+
>objB : Symbol(objB, Decl(narrowGenericTypeByInstanceOf.ts, 201, 7))
497536
}
498537

499538
const objAB = { a: 5, b: "hello" };
500-
>objAB : Symbol(objAB, Decl(narrowGenericTypeByInstanceOf.ts, 191, 7))
501-
>a : Symbol(a, Decl(narrowGenericTypeByInstanceOf.ts, 191, 17))
502-
>b : Symbol(b, Decl(narrowGenericTypeByInstanceOf.ts, 191, 23))
539+
>objAB : Symbol(objAB, Decl(narrowGenericTypeByInstanceOf.ts, 206, 7))
540+
>a : Symbol(a, Decl(narrowGenericTypeByInstanceOf.ts, 206, 17))
541+
>b : Symbol(b, Decl(narrowGenericTypeByInstanceOf.ts, 206, 23))
503542

504543
if (objAB instanceof Child) {
505-
>objAB : Symbol(objAB, Decl(narrowGenericTypeByInstanceOf.ts, 191, 7))
506-
>Child : Symbol(Child, Decl(narrowGenericTypeByInstanceOf.ts, 174, 29))
544+
>objAB : Symbol(objAB, Decl(narrowGenericTypeByInstanceOf.ts, 206, 7))
545+
>Child : Symbol(Child, Decl(narrowGenericTypeByInstanceOf.ts, 189, 29))
507546

508547
objAB; // Child<number, string>
509-
>objAB : Symbol(objAB, Decl(narrowGenericTypeByInstanceOf.ts, 191, 7))
548+
>objAB : Symbol(objAB, Decl(narrowGenericTypeByInstanceOf.ts, 206, 7))
510549
}
511550

512551
const objAX = { a: 5, x: 7 };
513-
>objAX : Symbol(objAX, Decl(narrowGenericTypeByInstanceOf.ts, 196, 7))
514-
>a : Symbol(a, Decl(narrowGenericTypeByInstanceOf.ts, 196, 17))
515-
>x : Symbol(x, Decl(narrowGenericTypeByInstanceOf.ts, 196, 23))
552+
>objAX : Symbol(objAX, Decl(narrowGenericTypeByInstanceOf.ts, 211, 7))
553+
>a : Symbol(a, Decl(narrowGenericTypeByInstanceOf.ts, 211, 17))
554+
>x : Symbol(x, Decl(narrowGenericTypeByInstanceOf.ts, 211, 23))
516555

517556
if (objAX instanceof Child) {
518-
>objAX : Symbol(objAX, Decl(narrowGenericTypeByInstanceOf.ts, 196, 7))
519-
>Child : Symbol(Child, Decl(narrowGenericTypeByInstanceOf.ts, 174, 29))
557+
>objAX : Symbol(objAX, Decl(narrowGenericTypeByInstanceOf.ts, 211, 7))
558+
>Child : Symbol(Child, Decl(narrowGenericTypeByInstanceOf.ts, 189, 29))
520559

521560
objAX; // Child<number, any>
522-
>objAX : Symbol(objAX, Decl(narrowGenericTypeByInstanceOf.ts, 196, 7))
561+
>objAX : Symbol(objAX, Decl(narrowGenericTypeByInstanceOf.ts, 211, 7))
523562
}
524563

525564
const objBX = { b: "hello", x: 7 };
526-
>objBX : Symbol(objBX, Decl(narrowGenericTypeByInstanceOf.ts, 201, 7))
527-
>b : Symbol(b, Decl(narrowGenericTypeByInstanceOf.ts, 201, 17))
528-
>x : Symbol(x, Decl(narrowGenericTypeByInstanceOf.ts, 201, 29))
565+
>objBX : Symbol(objBX, Decl(narrowGenericTypeByInstanceOf.ts, 216, 7))
566+
>b : Symbol(b, Decl(narrowGenericTypeByInstanceOf.ts, 216, 17))
567+
>x : Symbol(x, Decl(narrowGenericTypeByInstanceOf.ts, 216, 29))
529568

530569
if (objBX instanceof Child) {
531-
>objBX : Symbol(objBX, Decl(narrowGenericTypeByInstanceOf.ts, 201, 7))
532-
>Child : Symbol(Child, Decl(narrowGenericTypeByInstanceOf.ts, 174, 29))
570+
>objBX : Symbol(objBX, Decl(narrowGenericTypeByInstanceOf.ts, 216, 7))
571+
>Child : Symbol(Child, Decl(narrowGenericTypeByInstanceOf.ts, 189, 29))
533572

534573
objBX; // Child<any, string>
535-
>objBX : Symbol(objBX, Decl(narrowGenericTypeByInstanceOf.ts, 201, 7))
574+
>objBX : Symbol(objBX, Decl(narrowGenericTypeByInstanceOf.ts, 216, 7))
536575
}
537576

538577
const objABX = { a: 5, b: "hello", x: 7 };
539-
>objABX : Symbol(objABX, Decl(narrowGenericTypeByInstanceOf.ts, 206, 7))
540-
>a : Symbol(a, Decl(narrowGenericTypeByInstanceOf.ts, 206, 18))
541-
>b : Symbol(b, Decl(narrowGenericTypeByInstanceOf.ts, 206, 24))
542-
>x : Symbol(x, Decl(narrowGenericTypeByInstanceOf.ts, 206, 36))
578+
>objABX : Symbol(objABX, Decl(narrowGenericTypeByInstanceOf.ts, 221, 7))
579+
>a : Symbol(a, Decl(narrowGenericTypeByInstanceOf.ts, 221, 18))
580+
>b : Symbol(b, Decl(narrowGenericTypeByInstanceOf.ts, 221, 24))
581+
>x : Symbol(x, Decl(narrowGenericTypeByInstanceOf.ts, 221, 36))
543582

544583
if (objABX instanceof Child) {
545-
>objABX : Symbol(objABX, Decl(narrowGenericTypeByInstanceOf.ts, 206, 7))
546-
>Child : Symbol(Child, Decl(narrowGenericTypeByInstanceOf.ts, 174, 29))
584+
>objABX : Symbol(objABX, Decl(narrowGenericTypeByInstanceOf.ts, 221, 7))
585+
>Child : Symbol(Child, Decl(narrowGenericTypeByInstanceOf.ts, 189, 29))
547586

548587
objABX; // Child<number, string>
549-
>objABX : Symbol(objABX, Decl(narrowGenericTypeByInstanceOf.ts, 206, 7))
588+
>objABX : Symbol(objABX, Decl(narrowGenericTypeByInstanceOf.ts, 221, 7))
550589
}
551590
}
552591

0 commit comments

Comments
 (0)