Avoid elaborating on generic indexes (#28294)

This commit is contained in:
Wesley Wigham 2018-11-06 12:51:11 -08:00 committed by GitHub
parent 41d3f0ad57
commit d7390c03f0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 158 additions and 12 deletions

View file

@ -10936,8 +10936,9 @@ namespace ts {
let reportedError = false;
for (let status = iterator.next(); !status.done; status = iterator.next()) {
const { errorNode: prop, innerExpression: next, nameType, errorMessage } = status.value;
const sourcePropType = getIndexedAccessType(source, nameType, /*accessNode*/ undefined, errorType);
const targetPropType = getIndexedAccessType(target, nameType, /*accessNode*/ undefined, errorType);
if (targetPropType === errorType || targetPropType.flags & TypeFlags.IndexedAccess) continue; // Don't elaborate on indexes on generic variables
const sourcePropType = getIndexedAccessType(source, nameType, /*accessNode*/ undefined, errorType);
if (sourcePropType !== errorType && targetPropType !== errorType && !checkTypeRelatedTo(sourcePropType, targetPropType, relation, /*errorNode*/ undefined)) {
const elaborated = next && elaborateError(next, sourcePropType, targetPropType, relation, /*headMessage*/ undefined);
if (elaborated) {

View file

@ -0,0 +1,24 @@
tests/cases/compiler/errorElaborationDivesIntoApparentlyPresentPropsOnly.ts(2,5): error TS2322: Type '{ a: string; b: number; c: number; }' is not assignable to type 'T'.
tests/cases/compiler/errorElaborationDivesIntoApparentlyPresentPropsOnly.ts(6,5): error TS2322: Type '{ a: number; }' is not assignable to type 'T'.
tests/cases/compiler/errorElaborationDivesIntoApparentlyPresentPropsOnly.ts(10,5): error TS2322: Type '{ a: string; }' is not assignable to type 'T'.
==== tests/cases/compiler/errorElaborationDivesIntoApparentlyPresentPropsOnly.ts (3 errors) ====
function foo<T extends { a: string }>(x: T) {
x = { a: "abc", b: 20, c: 30 };
~
!!! error TS2322: Type '{ a: string; b: number; c: number; }' is not assignable to type 'T'.
}
function bar<T extends { a: string }>(x: T) {
x = { a: 20 };
~
!!! error TS2322: Type '{ a: number; }' is not assignable to type 'T'.
}
function baz<T extends { a: string }>(x: T) {
x = { a: "not ok" };
~
!!! error TS2322: Type '{ a: string; }' is not assignable to type 'T'.
}

View file

@ -0,0 +1,24 @@
//// [errorElaborationDivesIntoApparentlyPresentPropsOnly.ts]
function foo<T extends { a: string }>(x: T) {
x = { a: "abc", b: 20, c: 30 };
}
function bar<T extends { a: string }>(x: T) {
x = { a: 20 };
}
function baz<T extends { a: string }>(x: T) {
x = { a: "not ok" };
}
//// [errorElaborationDivesIntoApparentlyPresentPropsOnly.js]
function foo(x) {
x = { a: "abc", b: 20, c: 30 };
}
function bar(x) {
x = { a: 20 };
}
function baz(x) {
x = { a: "not ok" };
}

View file

@ -0,0 +1,39 @@
=== tests/cases/compiler/errorElaborationDivesIntoApparentlyPresentPropsOnly.ts ===
function foo<T extends { a: string }>(x: T) {
>foo : Symbol(foo, Decl(errorElaborationDivesIntoApparentlyPresentPropsOnly.ts, 0, 0))
>T : Symbol(T, Decl(errorElaborationDivesIntoApparentlyPresentPropsOnly.ts, 0, 13))
>a : Symbol(a, Decl(errorElaborationDivesIntoApparentlyPresentPropsOnly.ts, 0, 24))
>x : Symbol(x, Decl(errorElaborationDivesIntoApparentlyPresentPropsOnly.ts, 0, 38))
>T : Symbol(T, Decl(errorElaborationDivesIntoApparentlyPresentPropsOnly.ts, 0, 13))
x = { a: "abc", b: 20, c: 30 };
>x : Symbol(x, Decl(errorElaborationDivesIntoApparentlyPresentPropsOnly.ts, 0, 38))
>a : Symbol(a, Decl(errorElaborationDivesIntoApparentlyPresentPropsOnly.ts, 1, 9))
>b : Symbol(b, Decl(errorElaborationDivesIntoApparentlyPresentPropsOnly.ts, 1, 19))
>c : Symbol(c, Decl(errorElaborationDivesIntoApparentlyPresentPropsOnly.ts, 1, 26))
}
function bar<T extends { a: string }>(x: T) {
>bar : Symbol(bar, Decl(errorElaborationDivesIntoApparentlyPresentPropsOnly.ts, 2, 1))
>T : Symbol(T, Decl(errorElaborationDivesIntoApparentlyPresentPropsOnly.ts, 4, 13))
>a : Symbol(a, Decl(errorElaborationDivesIntoApparentlyPresentPropsOnly.ts, 4, 24))
>x : Symbol(x, Decl(errorElaborationDivesIntoApparentlyPresentPropsOnly.ts, 4, 38))
>T : Symbol(T, Decl(errorElaborationDivesIntoApparentlyPresentPropsOnly.ts, 4, 13))
x = { a: 20 };
>x : Symbol(x, Decl(errorElaborationDivesIntoApparentlyPresentPropsOnly.ts, 4, 38))
>a : Symbol(a, Decl(errorElaborationDivesIntoApparentlyPresentPropsOnly.ts, 5, 9))
}
function baz<T extends { a: string }>(x: T) {
>baz : Symbol(baz, Decl(errorElaborationDivesIntoApparentlyPresentPropsOnly.ts, 6, 1))
>T : Symbol(T, Decl(errorElaborationDivesIntoApparentlyPresentPropsOnly.ts, 8, 13))
>a : Symbol(a, Decl(errorElaborationDivesIntoApparentlyPresentPropsOnly.ts, 8, 24))
>x : Symbol(x, Decl(errorElaborationDivesIntoApparentlyPresentPropsOnly.ts, 8, 38))
>T : Symbol(T, Decl(errorElaborationDivesIntoApparentlyPresentPropsOnly.ts, 8, 13))
x = { a: "not ok" };
>x : Symbol(x, Decl(errorElaborationDivesIntoApparentlyPresentPropsOnly.ts, 8, 38))
>a : Symbol(a, Decl(errorElaborationDivesIntoApparentlyPresentPropsOnly.ts, 9, 9))
}

View file

@ -0,0 +1,44 @@
=== tests/cases/compiler/errorElaborationDivesIntoApparentlyPresentPropsOnly.ts ===
function foo<T extends { a: string }>(x: T) {
>foo : <T extends { a: string; }>(x: T) => void
>a : string
>x : T
x = { a: "abc", b: 20, c: 30 };
>x = { a: "abc", b: 20, c: 30 } : { a: string; b: number; c: number; }
>x : T
>{ a: "abc", b: 20, c: 30 } : { a: string; b: number; c: number; }
>a : string
>"abc" : "abc"
>b : number
>20 : 20
>c : number
>30 : 30
}
function bar<T extends { a: string }>(x: T) {
>bar : <T extends { a: string; }>(x: T) => void
>a : string
>x : T
x = { a: 20 };
>x = { a: 20 } : { a: number; }
>x : T
>{ a: 20 } : { a: number; }
>a : number
>20 : 20
}
function baz<T extends { a: string }>(x: T) {
>baz : <T extends { a: string; }>(x: T) => void
>a : string
>x : T
x = { a: "not ok" };
>x = { a: "not ok" } : { a: string; }
>x : T
>{ a: "not ok" } : { a: string; }
>a : string
>"not ok" : "not ok"
}

View file

@ -1,8 +1,10 @@
tests/cases/compiler/indexedAccessRelation.ts(16,25): error TS2322: Type 'T' is not assignable to type 'S["a"] & T'.
Type 'Foo' is not assignable to type 'S["a"] & T'.
Type 'Foo' is not assignable to type 'S["a"]'.
Type 'T' is not assignable to type 'S["a"]'.
tests/cases/compiler/indexedAccessRelation.ts(16,23): error TS2345: Argument of type '{ a: T; }' is not assignable to parameter of type 'Pick<S & State<T>, "a">'.
Types of property 'a' are incompatible.
Type 'T' is not assignable to type 'S["a"] & T'.
Type 'Foo' is not assignable to type 'S["a"] & T'.
Type 'Foo' is not assignable to type 'S["a"]'.
Type 'T' is not assignable to type 'S["a"]'.
Type 'Foo' is not assignable to type 'S["a"]'.
==== tests/cases/compiler/indexedAccessRelation.ts (1 errors) ====
@ -22,13 +24,14 @@ tests/cases/compiler/indexedAccessRelation.ts(16,25): error TS2322: Type 'T' is
{
foo(a: T) {
this.setState({ a: a });
~
!!! error TS2322: Type 'T' is not assignable to type 'S["a"] & T'.
!!! error TS2322: Type 'Foo' is not assignable to type 'S["a"] & T'.
!!! error TS2322: Type 'Foo' is not assignable to type 'S["a"]'.
!!! error TS2322: Type 'T' is not assignable to type 'S["a"]'.
!!! error TS2322: Type 'Foo' is not assignable to type 'S["a"]'.
!!! related TS6500 tests/cases/compiler/indexedAccessRelation.ts:8:5: The expected type comes from property 'a' which is declared here on type 'Pick<S & State<T>, "a">'
~~~~~~~~
!!! error TS2345: Argument of type '{ a: T; }' is not assignable to parameter of type 'Pick<S & State<T>, "a">'.
!!! error TS2345: Types of property 'a' are incompatible.
!!! error TS2345: Type 'T' is not assignable to type 'S["a"] & T'.
!!! error TS2345: Type 'Foo' is not assignable to type 'S["a"] & T'.
!!! error TS2345: Type 'Foo' is not assignable to type 'S["a"]'.
!!! error TS2345: Type 'T' is not assignable to type 'S["a"]'.
!!! error TS2345: Type 'Foo' is not assignable to type 'S["a"]'.
}
}

View file

@ -0,0 +1,11 @@
function foo<T extends { a: string }>(x: T) {
x = { a: "abc", b: 20, c: 30 };
}
function bar<T extends { a: string }>(x: T) {
x = { a: 20 };
}
function baz<T extends { a: string }>(x: T) {
x = { a: "not ok" };
}