Slightly less conservative check in isConstraintPosition (#46526)

* Slight adjustment to check in isConstraintPosition

* Add regression test
This commit is contained in:
Anders Hejlsberg 2021-10-26 11:54:46 -07:00 committed by GitHub
parent 44c63a757e
commit f424dfc18a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 159 additions and 1 deletions

View file

@ -24758,7 +24758,7 @@ namespace ts {
return parent.kind === SyntaxKind.PropertyAccessExpression ||
parent.kind === SyntaxKind.CallExpression && (parent as CallExpression).expression === node ||
parent.kind === SyntaxKind.ElementAccessExpression && (parent as ElementAccessExpression).expression === node &&
!(isGenericTypeWithoutNullableConstraint(type) && isGenericIndexType(getTypeOfExpression((parent as ElementAccessExpression).argumentExpression)));
!(someType(type, isGenericTypeWithoutNullableConstraint) && isGenericIndexType(getTypeOfExpression((parent as ElementAccessExpression).argumentExpression)));
}
function isGenericTypeWithUnionConstraint(type: Type) {

View file

@ -220,4 +220,24 @@ tests/cases/conformance/controlFlow/controlFlowGenericTypes.ts(168,9): error TS2
this.validateRow(row);
}
}
// Repro from #46495
interface Button {
type: "button";
text: string;
}
interface Checkbox {
type: "checkbox";
isChecked: boolean;
}
type Control = Button | Checkbox;
function update<T extends Control, K extends keyof T>(control : T | undefined, key: K, value: T[K]): void {
if (control !== undefined) {
control[key] = value;
}
}

View file

@ -190,6 +190,26 @@ class SqlTable<T> {
this.validateRow(row);
}
}
// Repro from #46495
interface Button {
type: "button";
text: string;
}
interface Checkbox {
type: "checkbox";
isChecked: boolean;
}
type Control = Button | Checkbox;
function update<T extends Control, K extends keyof T>(control : T | undefined, key: K, value: T[K]): void {
if (control !== undefined) {
control[key] = value;
}
}
//// [controlFlowGenericTypes.js]
@ -343,3 +363,8 @@ var SqlTable = /** @class */ (function () {
};
return SqlTable;
}());
function update(control, key, value) {
if (control !== undefined) {
control[key] = value;
}
}

View file

@ -574,3 +574,55 @@ class SqlTable<T> {
}
}
// Repro from #46495
interface Button {
>Button : Symbol(Button, Decl(controlFlowGenericTypes.ts, 190, 1))
type: "button";
>type : Symbol(Button.type, Decl(controlFlowGenericTypes.ts, 194, 18))
text: string;
>text : Symbol(Button.text, Decl(controlFlowGenericTypes.ts, 195, 19))
}
interface Checkbox {
>Checkbox : Symbol(Checkbox, Decl(controlFlowGenericTypes.ts, 197, 1))
type: "checkbox";
>type : Symbol(Checkbox.type, Decl(controlFlowGenericTypes.ts, 199, 20))
isChecked: boolean;
>isChecked : Symbol(Checkbox.isChecked, Decl(controlFlowGenericTypes.ts, 200, 21))
}
type Control = Button | Checkbox;
>Control : Symbol(Control, Decl(controlFlowGenericTypes.ts, 202, 1))
>Button : Symbol(Button, Decl(controlFlowGenericTypes.ts, 190, 1))
>Checkbox : Symbol(Checkbox, Decl(controlFlowGenericTypes.ts, 197, 1))
function update<T extends Control, K extends keyof T>(control : T | undefined, key: K, value: T[K]): void {
>update : Symbol(update, Decl(controlFlowGenericTypes.ts, 204, 33))
>T : Symbol(T, Decl(controlFlowGenericTypes.ts, 206, 16))
>Control : Symbol(Control, Decl(controlFlowGenericTypes.ts, 202, 1))
>K : Symbol(K, Decl(controlFlowGenericTypes.ts, 206, 34))
>T : Symbol(T, Decl(controlFlowGenericTypes.ts, 206, 16))
>control : Symbol(control, Decl(controlFlowGenericTypes.ts, 206, 54))
>T : Symbol(T, Decl(controlFlowGenericTypes.ts, 206, 16))
>key : Symbol(key, Decl(controlFlowGenericTypes.ts, 206, 78))
>K : Symbol(K, Decl(controlFlowGenericTypes.ts, 206, 34))
>value : Symbol(value, Decl(controlFlowGenericTypes.ts, 206, 86))
>T : Symbol(T, Decl(controlFlowGenericTypes.ts, 206, 16))
>K : Symbol(K, Decl(controlFlowGenericTypes.ts, 206, 34))
if (control !== undefined) {
>control : Symbol(control, Decl(controlFlowGenericTypes.ts, 206, 54))
>undefined : Symbol(undefined)
control[key] = value;
>control : Symbol(control, Decl(controlFlowGenericTypes.ts, 206, 54))
>key : Symbol(key, Decl(controlFlowGenericTypes.ts, 206, 78))
>value : Symbol(value, Decl(controlFlowGenericTypes.ts, 206, 86))
}
}

View file

@ -542,3 +542,44 @@ class SqlTable<T> {
}
}
// Repro from #46495
interface Button {
type: "button";
>type : "button"
text: string;
>text : string
}
interface Checkbox {
type: "checkbox";
>type : "checkbox"
isChecked: boolean;
>isChecked : boolean
}
type Control = Button | Checkbox;
>Control : Control
function update<T extends Control, K extends keyof T>(control : T | undefined, key: K, value: T[K]): void {
>update : <T extends Control, K extends keyof T>(control: T | undefined, key: K, value: T[K]) => void
>control : T | undefined
>key : K
>value : T[K]
if (control !== undefined) {
>control !== undefined : boolean
>control : T | undefined
>undefined : undefined
control[key] = value;
>control[key] = value : T[K]
>control[key] : T[K]
>control : T
>key : K
>value : T[K]
}
}

View file

@ -191,3 +191,23 @@ class SqlTable<T> {
this.validateRow(row);
}
}
// Repro from #46495
interface Button {
type: "button";
text: string;
}
interface Checkbox {
type: "checkbox";
isChecked: boolean;
}
type Control = Button | Checkbox;
function update<T extends Control, K extends keyof T>(control : T | undefined, key: K, value: T[K]): void {
if (control !== undefined) {
control[key] = value;
}
}