Skip to content

Commit 94bad93

Browse files
ahejlsbergmprobst
authored andcommitted
Slightly less conservative check in isConstraintPosition (microsoft#46526)
* Slight adjustment to check in isConstraintPosition * Add regression test
1 parent 9c4d9da commit 94bad93

File tree

6 files changed

+159
-1
lines changed

6 files changed

+159
-1
lines changed

src/compiler/checker.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -24758,7 +24758,7 @@ namespace ts {
2475824758
return parent.kind === SyntaxKind.PropertyAccessExpression ||
2475924759
parent.kind === SyntaxKind.CallExpression && (parent as CallExpression).expression === node ||
2476024760
parent.kind === SyntaxKind.ElementAccessExpression && (parent as ElementAccessExpression).expression === node &&
24761-
!(isGenericTypeWithoutNullableConstraint(type) && isGenericIndexType(getTypeOfExpression((parent as ElementAccessExpression).argumentExpression)));
24761+
!(someType(type, isGenericTypeWithoutNullableConstraint) && isGenericIndexType(getTypeOfExpression((parent as ElementAccessExpression).argumentExpression)));
2476224762
}
2476324763

2476424764
function isGenericTypeWithUnionConstraint(type: Type) {

tests/baselines/reference/controlFlowGenericTypes.errors.txt

+20
Original file line numberDiff line numberDiff line change
@@ -220,4 +220,24 @@ tests/cases/conformance/controlFlow/controlFlowGenericTypes.ts(168,9): error TS2
220220
this.validateRow(row);
221221
}
222222
}
223+
224+
// Repro from #46495
225+
226+
interface Button {
227+
type: "button";
228+
text: string;
229+
}
230+
231+
interface Checkbox {
232+
type: "checkbox";
233+
isChecked: boolean;
234+
}
235+
236+
type Control = Button | Checkbox;
237+
238+
function update<T extends Control, K extends keyof T>(control : T | undefined, key: K, value: T[K]): void {
239+
if (control !== undefined) {
240+
control[key] = value;
241+
}
242+
}
223243

tests/baselines/reference/controlFlowGenericTypes.js

+25
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,26 @@ class SqlTable<T> {
190190
this.validateRow(row);
191191
}
192192
}
193+
194+
// Repro from #46495
195+
196+
interface Button {
197+
type: "button";
198+
text: string;
199+
}
200+
201+
interface Checkbox {
202+
type: "checkbox";
203+
isChecked: boolean;
204+
}
205+
206+
type Control = Button | Checkbox;
207+
208+
function update<T extends Control, K extends keyof T>(control : T | undefined, key: K, value: T[K]): void {
209+
if (control !== undefined) {
210+
control[key] = value;
211+
}
212+
}
193213

194214

195215
//// [controlFlowGenericTypes.js]
@@ -343,3 +363,8 @@ var SqlTable = /** @class */ (function () {
343363
};
344364
return SqlTable;
345365
}());
366+
function update(control, key, value) {
367+
if (control !== undefined) {
368+
control[key] = value;
369+
}
370+
}

tests/baselines/reference/controlFlowGenericTypes.symbols

+52
Original file line numberDiff line numberDiff line change
@@ -574,3 +574,55 @@ class SqlTable<T> {
574574
}
575575
}
576576

577+
// Repro from #46495
578+
579+
interface Button {
580+
>Button : Symbol(Button, Decl(controlFlowGenericTypes.ts, 190, 1))
581+
582+
type: "button";
583+
>type : Symbol(Button.type, Decl(controlFlowGenericTypes.ts, 194, 18))
584+
585+
text: string;
586+
>text : Symbol(Button.text, Decl(controlFlowGenericTypes.ts, 195, 19))
587+
}
588+
589+
interface Checkbox {
590+
>Checkbox : Symbol(Checkbox, Decl(controlFlowGenericTypes.ts, 197, 1))
591+
592+
type: "checkbox";
593+
>type : Symbol(Checkbox.type, Decl(controlFlowGenericTypes.ts, 199, 20))
594+
595+
isChecked: boolean;
596+
>isChecked : Symbol(Checkbox.isChecked, Decl(controlFlowGenericTypes.ts, 200, 21))
597+
}
598+
599+
type Control = Button | Checkbox;
600+
>Control : Symbol(Control, Decl(controlFlowGenericTypes.ts, 202, 1))
601+
>Button : Symbol(Button, Decl(controlFlowGenericTypes.ts, 190, 1))
602+
>Checkbox : Symbol(Checkbox, Decl(controlFlowGenericTypes.ts, 197, 1))
603+
604+
function update<T extends Control, K extends keyof T>(control : T | undefined, key: K, value: T[K]): void {
605+
>update : Symbol(update, Decl(controlFlowGenericTypes.ts, 204, 33))
606+
>T : Symbol(T, Decl(controlFlowGenericTypes.ts, 206, 16))
607+
>Control : Symbol(Control, Decl(controlFlowGenericTypes.ts, 202, 1))
608+
>K : Symbol(K, Decl(controlFlowGenericTypes.ts, 206, 34))
609+
>T : Symbol(T, Decl(controlFlowGenericTypes.ts, 206, 16))
610+
>control : Symbol(control, Decl(controlFlowGenericTypes.ts, 206, 54))
611+
>T : Symbol(T, Decl(controlFlowGenericTypes.ts, 206, 16))
612+
>key : Symbol(key, Decl(controlFlowGenericTypes.ts, 206, 78))
613+
>K : Symbol(K, Decl(controlFlowGenericTypes.ts, 206, 34))
614+
>value : Symbol(value, Decl(controlFlowGenericTypes.ts, 206, 86))
615+
>T : Symbol(T, Decl(controlFlowGenericTypes.ts, 206, 16))
616+
>K : Symbol(K, Decl(controlFlowGenericTypes.ts, 206, 34))
617+
618+
if (control !== undefined) {
619+
>control : Symbol(control, Decl(controlFlowGenericTypes.ts, 206, 54))
620+
>undefined : Symbol(undefined)
621+
622+
control[key] = value;
623+
>control : Symbol(control, Decl(controlFlowGenericTypes.ts, 206, 54))
624+
>key : Symbol(key, Decl(controlFlowGenericTypes.ts, 206, 78))
625+
>value : Symbol(value, Decl(controlFlowGenericTypes.ts, 206, 86))
626+
}
627+
}
628+

tests/baselines/reference/controlFlowGenericTypes.types

+41
Original file line numberDiff line numberDiff line change
@@ -542,3 +542,44 @@ class SqlTable<T> {
542542
}
543543
}
544544

545+
// Repro from #46495
546+
547+
interface Button {
548+
type: "button";
549+
>type : "button"
550+
551+
text: string;
552+
>text : string
553+
}
554+
555+
interface Checkbox {
556+
type: "checkbox";
557+
>type : "checkbox"
558+
559+
isChecked: boolean;
560+
>isChecked : boolean
561+
}
562+
563+
type Control = Button | Checkbox;
564+
>Control : Control
565+
566+
function update<T extends Control, K extends keyof T>(control : T | undefined, key: K, value: T[K]): void {
567+
>update : <T extends Control, K extends keyof T>(control: T | undefined, key: K, value: T[K]) => void
568+
>control : T | undefined
569+
>key : K
570+
>value : T[K]
571+
572+
if (control !== undefined) {
573+
>control !== undefined : boolean
574+
>control : T | undefined
575+
>undefined : undefined
576+
577+
control[key] = value;
578+
>control[key] = value : T[K]
579+
>control[key] : T[K]
580+
>control : T
581+
>key : K
582+
>value : T[K]
583+
}
584+
}
585+

tests/cases/conformance/controlFlow/controlFlowGenericTypes.ts

+20
Original file line numberDiff line numberDiff line change
@@ -191,3 +191,23 @@ class SqlTable<T> {
191191
this.validateRow(row);
192192
}
193193
}
194+
195+
// Repro from #46495
196+
197+
interface Button {
198+
type: "button";
199+
text: string;
200+
}
201+
202+
interface Checkbox {
203+
type: "checkbox";
204+
isChecked: boolean;
205+
}
206+
207+
type Control = Button | Checkbox;
208+
209+
function update<T extends Control, K extends keyof T>(control : T | undefined, key: K, value: T[K]): void {
210+
if (control !== undefined) {
211+
control[key] = value;
212+
}
213+
}

0 commit comments

Comments
 (0)