From bda32aeee2af866073c3b80272f4a53720ff1a51 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 17 Jul 2018 21:52:24 -0700 Subject: [PATCH 1/4] Added test. --- .../compiler/objectLiteralsAgainstUnionsOfArrays01.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 tests/cases/compiler/objectLiteralsAgainstUnionsOfArrays01.ts diff --git a/tests/cases/compiler/objectLiteralsAgainstUnionsOfArrays01.ts b/tests/cases/compiler/objectLiteralsAgainstUnionsOfArrays01.ts new file mode 100644 index 0000000000000..d09b6b114bf14 --- /dev/null +++ b/tests/cases/compiler/objectLiteralsAgainstUnionsOfArrays01.ts @@ -0,0 +1,11 @@ +interface Foo { + bar: Bar | Bar[]; +} + +interface Bar { + prop: string; +} + +let x: Foo[] = [ + { bar: { prop: 100 } } +] From 36e26c1a3530779b62c69d6602aa7840d4eead2a Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 17 Jul 2018 21:52:36 -0700 Subject: [PATCH 2/4] Accepted baselines. --- ...LiteralsAgainstUnionsOfArrays01.errors.txt | 28 +++++++++++++++++ .../objectLiteralsAgainstUnionsOfArrays01.js | 18 +++++++++++ ...ectLiteralsAgainstUnionsOfArrays01.symbols | 27 ++++++++++++++++ ...bjectLiteralsAgainstUnionsOfArrays01.types | 31 +++++++++++++++++++ 4 files changed, 104 insertions(+) create mode 100644 tests/baselines/reference/objectLiteralsAgainstUnionsOfArrays01.errors.txt create mode 100644 tests/baselines/reference/objectLiteralsAgainstUnionsOfArrays01.js create mode 100644 tests/baselines/reference/objectLiteralsAgainstUnionsOfArrays01.symbols create mode 100644 tests/baselines/reference/objectLiteralsAgainstUnionsOfArrays01.types diff --git a/tests/baselines/reference/objectLiteralsAgainstUnionsOfArrays01.errors.txt b/tests/baselines/reference/objectLiteralsAgainstUnionsOfArrays01.errors.txt new file mode 100644 index 0000000000000..bba6e3906e062 --- /dev/null +++ b/tests/baselines/reference/objectLiteralsAgainstUnionsOfArrays01.errors.txt @@ -0,0 +1,28 @@ +tests/cases/compiler/objectLiteralsAgainstUnionsOfArrays01.ts(9,5): error TS2322: Type '{ bar: { prop: number; }; }[]' is not assignable to type 'Foo[]'. + Type '{ bar: { prop: number; }; }' is not assignable to type 'Foo'. + Types of property 'bar' are incompatible. + Type '{ prop: number; }' is not assignable to type 'Bar | Bar[]'. + Type '{ prop: number; }' is not assignable to type 'Bar[]'. + Property 'length' is missing in type '{ prop: number; }'. + + +==== tests/cases/compiler/objectLiteralsAgainstUnionsOfArrays01.ts (1 errors) ==== + interface Foo { + bar: Bar | Bar[]; + } + + interface Bar { + prop: string; + } + + let x: Foo[] = [ + ~ +!!! error TS2322: Type '{ bar: { prop: number; }; }[]' is not assignable to type 'Foo[]'. +!!! error TS2322: Type '{ bar: { prop: number; }; }' is not assignable to type 'Foo'. +!!! error TS2322: Types of property 'bar' are incompatible. +!!! error TS2322: Type '{ prop: number; }' is not assignable to type 'Bar | Bar[]'. +!!! error TS2322: Type '{ prop: number; }' is not assignable to type 'Bar[]'. +!!! error TS2322: Property 'length' is missing in type '{ prop: number; }'. + { bar: { prop: 100 } } + ] + \ No newline at end of file diff --git a/tests/baselines/reference/objectLiteralsAgainstUnionsOfArrays01.js b/tests/baselines/reference/objectLiteralsAgainstUnionsOfArrays01.js new file mode 100644 index 0000000000000..d7fbddd5cceac --- /dev/null +++ b/tests/baselines/reference/objectLiteralsAgainstUnionsOfArrays01.js @@ -0,0 +1,18 @@ +//// [objectLiteralsAgainstUnionsOfArrays01.ts] +interface Foo { + bar: Bar | Bar[]; +} + +interface Bar { + prop: string; +} + +let x: Foo[] = [ + { bar: { prop: 100 } } +] + + +//// [objectLiteralsAgainstUnionsOfArrays01.js] +var x = [ + { bar: { prop: 100 } } +]; diff --git a/tests/baselines/reference/objectLiteralsAgainstUnionsOfArrays01.symbols b/tests/baselines/reference/objectLiteralsAgainstUnionsOfArrays01.symbols new file mode 100644 index 0000000000000..248824334f04b --- /dev/null +++ b/tests/baselines/reference/objectLiteralsAgainstUnionsOfArrays01.symbols @@ -0,0 +1,27 @@ +=== tests/cases/compiler/objectLiteralsAgainstUnionsOfArrays01.ts === +interface Foo { +>Foo : Symbol(Foo, Decl(objectLiteralsAgainstUnionsOfArrays01.ts, 0, 0)) + + bar: Bar | Bar[]; +>bar : Symbol(Foo.bar, Decl(objectLiteralsAgainstUnionsOfArrays01.ts, 0, 15)) +>Bar : Symbol(Bar, Decl(objectLiteralsAgainstUnionsOfArrays01.ts, 2, 1)) +>Bar : Symbol(Bar, Decl(objectLiteralsAgainstUnionsOfArrays01.ts, 2, 1)) +} + +interface Bar { +>Bar : Symbol(Bar, Decl(objectLiteralsAgainstUnionsOfArrays01.ts, 2, 1)) + + prop: string; +>prop : Symbol(Bar.prop, Decl(objectLiteralsAgainstUnionsOfArrays01.ts, 4, 15)) +} + +let x: Foo[] = [ +>x : Symbol(x, Decl(objectLiteralsAgainstUnionsOfArrays01.ts, 8, 3)) +>Foo : Symbol(Foo, Decl(objectLiteralsAgainstUnionsOfArrays01.ts, 0, 0)) + + { bar: { prop: 100 } } +>bar : Symbol(bar, Decl(objectLiteralsAgainstUnionsOfArrays01.ts, 9, 3)) +>prop : Symbol(prop, Decl(objectLiteralsAgainstUnionsOfArrays01.ts, 9, 10)) + +] + diff --git a/tests/baselines/reference/objectLiteralsAgainstUnionsOfArrays01.types b/tests/baselines/reference/objectLiteralsAgainstUnionsOfArrays01.types new file mode 100644 index 0000000000000..6c841fdd3f212 --- /dev/null +++ b/tests/baselines/reference/objectLiteralsAgainstUnionsOfArrays01.types @@ -0,0 +1,31 @@ +=== tests/cases/compiler/objectLiteralsAgainstUnionsOfArrays01.ts === +interface Foo { +>Foo : Foo + + bar: Bar | Bar[]; +>bar : Bar | Bar[] +>Bar : Bar +>Bar : Bar +} + +interface Bar { +>Bar : Bar + + prop: string; +>prop : string +} + +let x: Foo[] = [ +>x : Foo[] +>Foo : Foo +>[ { bar: { prop: 100 } }] : { bar: { prop: number; }; }[] + + { bar: { prop: 100 } } +>{ bar: { prop: 100 } } : { bar: { prop: number; }; } +>bar : { prop: number; } +>{ prop: 100 } : { prop: number; } +>prop : number +>100 : 100 + +] + From 649f2944137b21621f3556fea8aafe0ef5f2000e Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 17 Jul 2018 21:54:33 -0700 Subject: [PATCH 3/4] Elaborate on the first non-array type when object literals are compared against 'T | T[]'. --- src/compiler/checker.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index e59641bed412e..88983c9eff959 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -11182,7 +11182,8 @@ namespace ts { if (reportErrors) { const bestMatchingType = findMatchingDiscriminantType(source, target) || - findMatchingTypeReferenceOrTypeAliasReference(source, target); + findMatchingTypeReferenceOrTypeAliasReference(source, target) || + findBestTypeForObjectLiteral(source, target); isRelatedTo(source, bestMatchingType || targetTypes[targetTypes.length - 1], /*reportErrors*/ true); } @@ -11207,6 +11208,11 @@ namespace ts { } } + function findBestTypeForObjectLiteral(source: Type, unionTarget: UnionOrIntersectionType) { + if (getObjectFlags(source) & ObjectFlags.ObjectLiteral && forEachType(unionTarget, isArrayLikeType)) { + return find(unionTarget.types, t => !isArrayLikeType(t)); + } + } // Keep this up-to-date with the same logic within `getApparentTypeOfContextualType`, since they should behave similarly function findMatchingDiscriminantType(source: Type, target: UnionOrIntersectionType) { From 806a5385ccf7aa41791bff42f278eab0ff9c8460 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 17 Jul 2018 21:58:02 -0700 Subject: [PATCH 4/4] Accepted baselines. --- .../objectLiteralsAgainstUnionsOfArrays01.errors.txt | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tests/baselines/reference/objectLiteralsAgainstUnionsOfArrays01.errors.txt b/tests/baselines/reference/objectLiteralsAgainstUnionsOfArrays01.errors.txt index bba6e3906e062..13cc52dd2c66b 100644 --- a/tests/baselines/reference/objectLiteralsAgainstUnionsOfArrays01.errors.txt +++ b/tests/baselines/reference/objectLiteralsAgainstUnionsOfArrays01.errors.txt @@ -2,8 +2,9 @@ tests/cases/compiler/objectLiteralsAgainstUnionsOfArrays01.ts(9,5): error TS2322 Type '{ bar: { prop: number; }; }' is not assignable to type 'Foo'. Types of property 'bar' are incompatible. Type '{ prop: number; }' is not assignable to type 'Bar | Bar[]'. - Type '{ prop: number; }' is not assignable to type 'Bar[]'. - Property 'length' is missing in type '{ prop: number; }'. + Type '{ prop: number; }' is not assignable to type 'Bar'. + Types of property 'prop' are incompatible. + Type 'number' is not assignable to type 'string'. ==== tests/cases/compiler/objectLiteralsAgainstUnionsOfArrays01.ts (1 errors) ==== @@ -21,8 +22,9 @@ tests/cases/compiler/objectLiteralsAgainstUnionsOfArrays01.ts(9,5): error TS2322 !!! error TS2322: Type '{ bar: { prop: number; }; }' is not assignable to type 'Foo'. !!! error TS2322: Types of property 'bar' are incompatible. !!! error TS2322: Type '{ prop: number; }' is not assignable to type 'Bar | Bar[]'. -!!! error TS2322: Type '{ prop: number; }' is not assignable to type 'Bar[]'. -!!! error TS2322: Property 'length' is missing in type '{ prop: number; }'. +!!! error TS2322: Type '{ prop: number; }' is not assignable to type 'Bar'. +!!! error TS2322: Types of property 'prop' are incompatible. +!!! error TS2322: Type 'number' is not assignable to type 'string'. { bar: { prop: 100 } } ] \ No newline at end of file