Skip to content

Commit ded20c6

Browse files
TypeScript Botahejlsberg
TypeScript Bot
andauthored
Cherry-pick PR microsoft#47953 into release-4.6 (microsoft#47957)
Component commits: aa1c25d Remove unnecessary check in getNarrowableTypeForReference f4dcf88 Add regression test Co-authored-by: Anders Hejlsberg <[email protected]>
1 parent 57bd608 commit ded20c6

File tree

5 files changed

+231
-1
lines changed

5 files changed

+231
-1
lines changed

Diff for: src/compiler/checker.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -25051,7 +25051,7 @@ namespace ts {
2505125051
const substituteConstraints = !(checkMode && checkMode & CheckMode.Inferential) &&
2505225052
someType(type, isGenericTypeWithUnionConstraint) &&
2505325053
(isConstraintPosition(type, reference) || hasContextualTypeWithNoGenericTypes(reference, checkMode));
25054-
return substituteConstraints ? mapType(type, t => t.flags & TypeFlags.Instantiable && !isMappedTypeGenericIndexedAccess(t) ? getBaseConstraintOrType(t) : t) : type;
25054+
return substituteConstraints ? mapType(type, t => t.flags & TypeFlags.Instantiable ? getBaseConstraintOrType(t) : t) : type;
2505525055
}
2505625056

2505725057
function isExportOrExportExpression(location: Node) {

Diff for: tests/baselines/reference/correlatedUnions.js

+53
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,34 @@ function f3<K extends keyof ArgMap>(funcs: Funcs, key: K, arg: ArgMap[K]) {
181181
function f4<K extends keyof ArgMap>(x: Funcs[keyof ArgMap], y: Funcs[K]) {
182182
x = y;
183183
}
184+
185+
// Repro from #47890
186+
187+
interface MyObj {
188+
someKey: {
189+
name: string;
190+
}
191+
someOtherKey: {
192+
name: number;
193+
}
194+
}
195+
196+
const ref: MyObj = {
197+
someKey: { name: "" },
198+
someOtherKey: { name: 42 }
199+
};
200+
201+
function func<K extends keyof MyObj>(k: K): MyObj[K]['name'] | undefined {
202+
const myObj: Partial<MyObj>[K] = ref[k];
203+
if (myObj) {
204+
return myObj.name;
205+
}
206+
const myObj2: Partial<MyObj>[keyof MyObj] = ref[k];
207+
if (myObj2) {
208+
return myObj2.name;
209+
}
210+
return undefined;
211+
}
184212

185213

186214
//// [correlatedUnions.js]
@@ -282,6 +310,21 @@ function f3(funcs, key, arg) {
282310
function f4(x, y) {
283311
x = y;
284312
}
313+
var ref = {
314+
someKey: { name: "" },
315+
someOtherKey: { name: 42 }
316+
};
317+
function func(k) {
318+
var myObj = ref[k];
319+
if (myObj) {
320+
return myObj.name;
321+
}
322+
var myObj2 = ref[k];
323+
if (myObj2) {
324+
return myObj2.name;
325+
}
326+
return undefined;
327+
}
285328

286329

287330
//// [correlatedUnions.d.ts]
@@ -398,3 +441,13 @@ declare function f1<K extends keyof ArgMap>(funcs: Funcs, key: K, arg: ArgMap[K]
398441
declare function f2<K extends keyof ArgMap>(funcs: Funcs, key: K, arg: ArgMap[K]): void;
399442
declare function f3<K extends keyof ArgMap>(funcs: Funcs, key: K, arg: ArgMap[K]): void;
400443
declare function f4<K extends keyof ArgMap>(x: Funcs[keyof ArgMap], y: Funcs[K]): void;
444+
interface MyObj {
445+
someKey: {
446+
name: string;
447+
};
448+
someOtherKey: {
449+
name: number;
450+
};
451+
}
452+
declare const ref: MyObj;
453+
declare function func<K extends keyof MyObj>(k: K): MyObj[K]['name'] | undefined;

Diff for: tests/baselines/reference/correlatedUnions.symbols

+78
Original file line numberDiff line numberDiff line change
@@ -675,3 +675,81 @@ function f4<K extends keyof ArgMap>(x: Funcs[keyof ArgMap], y: Funcs[K]) {
675675
>y : Symbol(y, Decl(correlatedUnions.ts, 179, 59))
676676
}
677677

678+
// Repro from #47890
679+
680+
interface MyObj {
681+
>MyObj : Symbol(MyObj, Decl(correlatedUnions.ts, 181, 1))
682+
683+
someKey: {
684+
>someKey : Symbol(MyObj.someKey, Decl(correlatedUnions.ts, 185, 17))
685+
686+
name: string;
687+
>name : Symbol(name, Decl(correlatedUnions.ts, 186, 14))
688+
}
689+
someOtherKey: {
690+
>someOtherKey : Symbol(MyObj.someOtherKey, Decl(correlatedUnions.ts, 188, 5))
691+
692+
name: number;
693+
>name : Symbol(name, Decl(correlatedUnions.ts, 189, 19))
694+
}
695+
}
696+
697+
const ref: MyObj = {
698+
>ref : Symbol(ref, Decl(correlatedUnions.ts, 194, 5))
699+
>MyObj : Symbol(MyObj, Decl(correlatedUnions.ts, 181, 1))
700+
701+
someKey: { name: "" },
702+
>someKey : Symbol(someKey, Decl(correlatedUnions.ts, 194, 20))
703+
>name : Symbol(name, Decl(correlatedUnions.ts, 195, 14))
704+
705+
someOtherKey: { name: 42 }
706+
>someOtherKey : Symbol(someOtherKey, Decl(correlatedUnions.ts, 195, 26))
707+
>name : Symbol(name, Decl(correlatedUnions.ts, 196, 19))
708+
709+
};
710+
711+
function func<K extends keyof MyObj>(k: K): MyObj[K]['name'] | undefined {
712+
>func : Symbol(func, Decl(correlatedUnions.ts, 197, 2))
713+
>K : Symbol(K, Decl(correlatedUnions.ts, 199, 14))
714+
>MyObj : Symbol(MyObj, Decl(correlatedUnions.ts, 181, 1))
715+
>k : Symbol(k, Decl(correlatedUnions.ts, 199, 37))
716+
>K : Symbol(K, Decl(correlatedUnions.ts, 199, 14))
717+
>MyObj : Symbol(MyObj, Decl(correlatedUnions.ts, 181, 1))
718+
>K : Symbol(K, Decl(correlatedUnions.ts, 199, 14))
719+
720+
const myObj: Partial<MyObj>[K] = ref[k];
721+
>myObj : Symbol(myObj, Decl(correlatedUnions.ts, 200, 9))
722+
>Partial : Symbol(Partial, Decl(lib.es5.d.ts, --, --))
723+
>MyObj : Symbol(MyObj, Decl(correlatedUnions.ts, 181, 1))
724+
>K : Symbol(K, Decl(correlatedUnions.ts, 199, 14))
725+
>ref : Symbol(ref, Decl(correlatedUnions.ts, 194, 5))
726+
>k : Symbol(k, Decl(correlatedUnions.ts, 199, 37))
727+
728+
if (myObj) {
729+
>myObj : Symbol(myObj, Decl(correlatedUnions.ts, 200, 9))
730+
731+
return myObj.name;
732+
>myObj.name : Symbol(name, Decl(correlatedUnions.ts, 186, 14), Decl(correlatedUnions.ts, 189, 19))
733+
>myObj : Symbol(myObj, Decl(correlatedUnions.ts, 200, 9))
734+
>name : Symbol(name, Decl(correlatedUnions.ts, 186, 14), Decl(correlatedUnions.ts, 189, 19))
735+
}
736+
const myObj2: Partial<MyObj>[keyof MyObj] = ref[k];
737+
>myObj2 : Symbol(myObj2, Decl(correlatedUnions.ts, 204, 9))
738+
>Partial : Symbol(Partial, Decl(lib.es5.d.ts, --, --))
739+
>MyObj : Symbol(MyObj, Decl(correlatedUnions.ts, 181, 1))
740+
>MyObj : Symbol(MyObj, Decl(correlatedUnions.ts, 181, 1))
741+
>ref : Symbol(ref, Decl(correlatedUnions.ts, 194, 5))
742+
>k : Symbol(k, Decl(correlatedUnions.ts, 199, 37))
743+
744+
if (myObj2) {
745+
>myObj2 : Symbol(myObj2, Decl(correlatedUnions.ts, 204, 9))
746+
747+
return myObj2.name;
748+
>myObj2.name : Symbol(name, Decl(correlatedUnions.ts, 186, 14), Decl(correlatedUnions.ts, 189, 19))
749+
>myObj2 : Symbol(myObj2, Decl(correlatedUnions.ts, 204, 9))
750+
>name : Symbol(name, Decl(correlatedUnions.ts, 186, 14), Decl(correlatedUnions.ts, 189, 19))
751+
}
752+
return undefined;
753+
>undefined : Symbol(undefined)
754+
}
755+

Diff for: tests/baselines/reference/correlatedUnions.types

+71
Original file line numberDiff line numberDiff line change
@@ -624,3 +624,74 @@ function f4<K extends keyof ArgMap>(x: Funcs[keyof ArgMap], y: Funcs[K]) {
624624
>y : Funcs[K]
625625
}
626626

627+
// Repro from #47890
628+
629+
interface MyObj {
630+
someKey: {
631+
>someKey : { name: string; }
632+
633+
name: string;
634+
>name : string
635+
}
636+
someOtherKey: {
637+
>someOtherKey : { name: number; }
638+
639+
name: number;
640+
>name : number
641+
}
642+
}
643+
644+
const ref: MyObj = {
645+
>ref : MyObj
646+
>{ someKey: { name: "" }, someOtherKey: { name: 42 }} : { someKey: { name: string; }; someOtherKey: { name: number; }; }
647+
648+
someKey: { name: "" },
649+
>someKey : { name: string; }
650+
>{ name: "" } : { name: string; }
651+
>name : string
652+
>"" : ""
653+
654+
someOtherKey: { name: 42 }
655+
>someOtherKey : { name: number; }
656+
>{ name: 42 } : { name: number; }
657+
>name : number
658+
>42 : 42
659+
660+
};
661+
662+
function func<K extends keyof MyObj>(k: K): MyObj[K]['name'] | undefined {
663+
>func : <K extends keyof MyObj>(k: K) => MyObj[K]['name'] | undefined
664+
>k : K
665+
666+
const myObj: Partial<MyObj>[K] = ref[k];
667+
>myObj : Partial<MyObj>[K]
668+
>ref[k] : MyObj[K]
669+
>ref : MyObj
670+
>k : K
671+
672+
if (myObj) {
673+
>myObj : Partial<MyObj>[K]
674+
675+
return myObj.name;
676+
>myObj.name : string | number
677+
>myObj : { name: string; } | { name: number; }
678+
>name : string | number
679+
}
680+
const myObj2: Partial<MyObj>[keyof MyObj] = ref[k];
681+
>myObj2 : { name: string; } | { name: number; } | undefined
682+
>ref[k] : { name: string; } | { name: number; }
683+
>ref : MyObj
684+
>k : K
685+
686+
if (myObj2) {
687+
>myObj2 : { name: string; } | { name: number; }
688+
689+
return myObj2.name;
690+
>myObj2.name : string | number
691+
>myObj2 : { name: string; } | { name: number; }
692+
>name : string | number
693+
}
694+
return undefined;
695+
>undefined : undefined
696+
}
697+

Diff for: tests/cases/compiler/correlatedUnions.ts

+28
Original file line numberDiff line numberDiff line change
@@ -183,3 +183,31 @@ function f3<K extends keyof ArgMap>(funcs: Funcs, key: K, arg: ArgMap[K]) {
183183
function f4<K extends keyof ArgMap>(x: Funcs[keyof ArgMap], y: Funcs[K]) {
184184
x = y;
185185
}
186+
187+
// Repro from #47890
188+
189+
interface MyObj {
190+
someKey: {
191+
name: string;
192+
}
193+
someOtherKey: {
194+
name: number;
195+
}
196+
}
197+
198+
const ref: MyObj = {
199+
someKey: { name: "" },
200+
someOtherKey: { name: 42 }
201+
};
202+
203+
function func<K extends keyof MyObj>(k: K): MyObj[K]['name'] | undefined {
204+
const myObj: Partial<MyObj>[K] = ref[k];
205+
if (myObj) {
206+
return myObj.name;
207+
}
208+
const myObj2: Partial<MyObj>[keyof MyObj] = ref[k];
209+
if (myObj2) {
210+
return myObj2.name;
211+
}
212+
return undefined;
213+
}

0 commit comments

Comments
 (0)