Merge pull request #28780 from Microsoft/singlyOverlappyTypes

Singly overlappy types
This commit is contained in:
Daniel Rosenwasser
2018-11-30 17:58:34 -08:00
committed by GitHub
7 changed files with 210 additions and 8 deletions
+2 -2
View File
@@ -11977,7 +11977,7 @@ namespace ts {
matchingCount = Infinity;
}
else if (overlap.flags & TypeFlags.Union) {
// Some subset overlap if we have only string literals.
// We only want to account for literal types otherwise.
// If we have a union of index types, it seems likely that we
// needed to elaborate between two generic mapped types anyway.
const len = length(filter((overlap as UnionType).types, isUnitType));
@@ -11986,7 +11986,7 @@ namespace ts {
matchingCount = len;
}
}
else if (!(overlap.flags & TypeFlags.Never) && 1 >= matchingCount) {
else if (isUnitType(overlap) && 1 >= matchingCount) {
bestMatch = target;
matchingCount = 1;
}
@@ -8,9 +8,17 @@ tests/cases/compiler/errorsOnUnionsOfOverlappingObjects01.ts(19,3): error TS2345
Type 'string' is not assignable to type 'number'.
tests/cases/compiler/errorsOnUnionsOfOverlappingObjects01.ts(24,5): error TS2345: Argument of type '{ a: string; b: string; }' is not assignable to parameter of type 'Bar | Other'.
Object literal may only specify known properties, and 'a' does not exist in type 'Bar | Other'.
tests/cases/compiler/errorsOnUnionsOfOverlappingObjects01.ts(42,10): error TS2345: Argument of type '{ dog: string; }' is not assignable to parameter of type 'ExoticAnimal'.
Property 'cat' is missing in type '{ dog: string; }' but required in type 'CatDog'.
tests/cases/compiler/errorsOnUnionsOfOverlappingObjects01.ts(43,10): error TS2345: Argument of type '{ man: string; bear: string; }' is not assignable to parameter of type 'ExoticAnimal'.
Property 'pig' is missing in type '{ man: string; bear: string; }' but required in type 'ManBearPig'.
tests/cases/compiler/errorsOnUnionsOfOverlappingObjects01.ts(46,26): error TS2345: Argument of type '{ man: string; beer: string; }' is not assignable to parameter of type 'ExoticAnimal'.
Object literal may only specify known properties, and 'beer' does not exist in type 'ExoticAnimal'.
tests/cases/compiler/errorsOnUnionsOfOverlappingObjects01.ts(47,10): error TS2345: Argument of type '{ man: string; beer: string; }' is not assignable to parameter of type 'ExoticAnimal'.
Type '{ man: string; beer: string; }' is missing the following properties from type 'ManBearPig': bear, pig
==== tests/cases/compiler/errorsOnUnionsOfOverlappingObjects01.ts (3 errors) ====
==== tests/cases/compiler/errorsOnUnionsOfOverlappingObjects01.ts (7 errors) ====
interface Foo {
a: string;
b: number;
@@ -53,4 +61,35 @@ tests/cases/compiler/errorsOnUnionsOfOverlappingObjects01.ts(24,5): error TS2345
h(x);
h({ a: '', b: '' })
interface CatDog { cat: any, dog: any }
interface ManBearPig { man: any, bear: any, pig: any }
interface Platypus { platypus: any }
type ExoticAnimal =
| CatDog
| ManBearPig
| Platypus;
declare function addToZoo(animal: ExoticAnimal): void;
addToZoo({ dog: "Barky McBarkface" });
~~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2345: Argument of type '{ dog: string; }' is not assignable to parameter of type 'ExoticAnimal'.
!!! error TS2345: Property 'cat' is missing in type '{ dog: string; }' but required in type 'CatDog'.
!!! related TS2728 tests/cases/compiler/errorsOnUnionsOfOverlappingObjects01.ts:31:20: 'cat' is declared here.
addToZoo({ man: "Manny", bear: "Coffee" });
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2345: Argument of type '{ man: string; bear: string; }' is not assignable to parameter of type 'ExoticAnimal'.
!!! error TS2345: Property 'pig' is missing in type '{ man: string; bear: string; }' but required in type 'ManBearPig'.
!!! related TS2728 tests/cases/compiler/errorsOnUnionsOfOverlappingObjects01.ts:32:45: 'pig' is declared here.
const manBeer = { man: "Manny", beer: "Coffee" };
addToZoo({ man: "Manny", beer: "Coffee" });
~~~~~~~~~~~~~~
!!! error TS2345: Argument of type '{ man: string; beer: string; }' is not assignable to parameter of type 'ExoticAnimal'.
!!! error TS2345: Object literal may only specify known properties, and 'beer' does not exist in type 'ExoticAnimal'.
addToZoo(manBeer);
~~~~~~~
!!! error TS2345: Argument of type '{ man: string; beer: string; }' is not assignable to parameter of type 'ExoticAnimal'.
!!! error TS2345: Type '{ man: string; beer: string; }' is missing the following properties from type 'ManBearPig': bear, pig
@@ -28,7 +28,24 @@ declare function h(x: Foo | Bar | Other): any;
h(x);
h({ a: '', b: '' })
interface CatDog { cat: any, dog: any }
interface ManBearPig { man: any, bear: any, pig: any }
interface Platypus { platypus: any }
type ExoticAnimal =
| CatDog
| ManBearPig
| Platypus;
declare function addToZoo(animal: ExoticAnimal): void;
addToZoo({ dog: "Barky McBarkface" });
addToZoo({ man: "Manny", bear: "Coffee" });
const manBeer = { man: "Manny", beer: "Coffee" };
addToZoo({ man: "Manny", beer: "Coffee" });
addToZoo(manBeer);
//// [errorsOnUnionsOfOverlappingObjects01.js]
"use strict";
@@ -41,3 +58,8 @@ g(exports.x);
g({ a: '', b: '' });
h(exports.x);
h({ a: '', b: '' });
addToZoo({ dog: "Barky McBarkface" });
addToZoo({ man: "Manny", bear: "Coffee" });
var manBeer = { man: "Manny", beer: "Coffee" };
addToZoo({ man: "Manny", beer: "Coffee" });
addToZoo(manBeer);
@@ -75,3 +75,58 @@ h({ a: '', b: '' })
>a : Symbol(a, Decl(errorsOnUnionsOfOverlappingObjects01.ts, 28, 3))
>b : Symbol(b, Decl(errorsOnUnionsOfOverlappingObjects01.ts, 28, 10))
interface CatDog { cat: any, dog: any }
>CatDog : Symbol(CatDog, Decl(errorsOnUnionsOfOverlappingObjects01.ts, 28, 19))
>cat : Symbol(CatDog.cat, Decl(errorsOnUnionsOfOverlappingObjects01.ts, 30, 18))
>dog : Symbol(CatDog.dog, Decl(errorsOnUnionsOfOverlappingObjects01.ts, 30, 28))
interface ManBearPig { man: any, bear: any, pig: any }
>ManBearPig : Symbol(ManBearPig, Decl(errorsOnUnionsOfOverlappingObjects01.ts, 30, 39))
>man : Symbol(ManBearPig.man, Decl(errorsOnUnionsOfOverlappingObjects01.ts, 31, 22))
>bear : Symbol(ManBearPig.bear, Decl(errorsOnUnionsOfOverlappingObjects01.ts, 31, 32))
>pig : Symbol(ManBearPig.pig, Decl(errorsOnUnionsOfOverlappingObjects01.ts, 31, 43))
interface Platypus { platypus: any }
>Platypus : Symbol(Platypus, Decl(errorsOnUnionsOfOverlappingObjects01.ts, 31, 54))
>platypus : Symbol(Platypus.platypus, Decl(errorsOnUnionsOfOverlappingObjects01.ts, 32, 20))
type ExoticAnimal =
>ExoticAnimal : Symbol(ExoticAnimal, Decl(errorsOnUnionsOfOverlappingObjects01.ts, 32, 36))
| CatDog
>CatDog : Symbol(CatDog, Decl(errorsOnUnionsOfOverlappingObjects01.ts, 28, 19))
| ManBearPig
>ManBearPig : Symbol(ManBearPig, Decl(errorsOnUnionsOfOverlappingObjects01.ts, 30, 39))
| Platypus;
>Platypus : Symbol(Platypus, Decl(errorsOnUnionsOfOverlappingObjects01.ts, 31, 54))
declare function addToZoo(animal: ExoticAnimal): void;
>addToZoo : Symbol(addToZoo, Decl(errorsOnUnionsOfOverlappingObjects01.ts, 37, 15))
>animal : Symbol(animal, Decl(errorsOnUnionsOfOverlappingObjects01.ts, 39, 26))
>ExoticAnimal : Symbol(ExoticAnimal, Decl(errorsOnUnionsOfOverlappingObjects01.ts, 32, 36))
addToZoo({ dog: "Barky McBarkface" });
>addToZoo : Symbol(addToZoo, Decl(errorsOnUnionsOfOverlappingObjects01.ts, 37, 15))
>dog : Symbol(dog, Decl(errorsOnUnionsOfOverlappingObjects01.ts, 41, 10))
addToZoo({ man: "Manny", bear: "Coffee" });
>addToZoo : Symbol(addToZoo, Decl(errorsOnUnionsOfOverlappingObjects01.ts, 37, 15))
>man : Symbol(man, Decl(errorsOnUnionsOfOverlappingObjects01.ts, 42, 10))
>bear : Symbol(bear, Decl(errorsOnUnionsOfOverlappingObjects01.ts, 42, 24))
const manBeer = { man: "Manny", beer: "Coffee" };
>manBeer : Symbol(manBeer, Decl(errorsOnUnionsOfOverlappingObjects01.ts, 44, 5))
>man : Symbol(man, Decl(errorsOnUnionsOfOverlappingObjects01.ts, 44, 17))
>beer : Symbol(beer, Decl(errorsOnUnionsOfOverlappingObjects01.ts, 44, 31))
addToZoo({ man: "Manny", beer: "Coffee" });
>addToZoo : Symbol(addToZoo, Decl(errorsOnUnionsOfOverlappingObjects01.ts, 37, 15))
>man : Symbol(man, Decl(errorsOnUnionsOfOverlappingObjects01.ts, 45, 10))
>beer : Symbol(beer, Decl(errorsOnUnionsOfOverlappingObjects01.ts, 45, 24))
addToZoo(manBeer);
>addToZoo : Symbol(addToZoo, Decl(errorsOnUnionsOfOverlappingObjects01.ts, 37, 15))
>manBeer : Symbol(manBeer, Decl(errorsOnUnionsOfOverlappingObjects01.ts, 44, 5))
@@ -80,3 +80,64 @@ h({ a: '', b: '' })
>b : string
>'' : ""
interface CatDog { cat: any, dog: any }
>cat : any
>dog : any
interface ManBearPig { man: any, bear: any, pig: any }
>man : any
>bear : any
>pig : any
interface Platypus { platypus: any }
>platypus : any
type ExoticAnimal =
>ExoticAnimal : ExoticAnimal
| CatDog
| ManBearPig
| Platypus;
declare function addToZoo(animal: ExoticAnimal): void;
>addToZoo : (animal: ExoticAnimal) => void
>animal : ExoticAnimal
addToZoo({ dog: "Barky McBarkface" });
>addToZoo({ dog: "Barky McBarkface" }) : void
>addToZoo : (animal: ExoticAnimal) => void
>{ dog: "Barky McBarkface" } : { dog: string; }
>dog : string
>"Barky McBarkface" : "Barky McBarkface"
addToZoo({ man: "Manny", bear: "Coffee" });
>addToZoo({ man: "Manny", bear: "Coffee" }) : void
>addToZoo : (animal: ExoticAnimal) => void
>{ man: "Manny", bear: "Coffee" } : { man: string; bear: string; }
>man : string
>"Manny" : "Manny"
>bear : string
>"Coffee" : "Coffee"
const manBeer = { man: "Manny", beer: "Coffee" };
>manBeer : { man: string; beer: string; }
>{ man: "Manny", beer: "Coffee" } : { man: string; beer: string; }
>man : string
>"Manny" : "Manny"
>beer : string
>"Coffee" : "Coffee"
addToZoo({ man: "Manny", beer: "Coffee" });
>addToZoo({ man: "Manny", beer: "Coffee" }) : void
>addToZoo : (animal: ExoticAnimal) => void
>{ man: "Manny", beer: "Coffee" } : { man: string; beer: string; }
>man : string
>"Manny" : "Manny"
>beer : string
>"Coffee" : "Coffee"
addToZoo(manBeer);
>addToZoo(manBeer) : void
>addToZoo : (animal: ExoticAnimal) => void
>manBeer : { man: string; beer: string; }
@@ -5,7 +5,11 @@ tests/cases/compiler/unionTypeWithRecursiveSubtypeReduction2.ts(19,1): error TS2
tests/cases/compiler/unionTypeWithRecursiveSubtypeReduction2.ts(20,1): error TS2322: Type 'Class' is not assignable to type 'Property'.
Types of property 'parent' are incompatible.
Type 'Namespace' is not assignable to type 'Module | Class'.
Property 'parent' is missing in type 'Namespace' but required in type 'Class'.
Type 'Namespace' is not assignable to type 'Module'.
Types of property 'members' are incompatible.
Type '(Class | Property)[]' is not assignable to type 'Class[]'.
Type 'Class | Property' is not assignable to type 'Class'.
Type 'Property' is not assignable to type 'Class'.
==== tests/cases/compiler/unionTypeWithRecursiveSubtypeReduction2.ts (2 errors) ====
@@ -39,6 +43,9 @@ tests/cases/compiler/unionTypeWithRecursiveSubtypeReduction2.ts(20,1): error TS2
!!! error TS2322: Type 'Class' is not assignable to type 'Property'.
!!! error TS2322: Types of property 'parent' are incompatible.
!!! error TS2322: Type 'Namespace' is not assignable to type 'Module | Class'.
!!! error TS2322: Property 'parent' is missing in type 'Namespace' but required in type 'Class'.
!!! related TS2728 tests/cases/compiler/unionTypeWithRecursiveSubtypeReduction2.ts:10:12: 'parent' is declared here.
!!! error TS2322: Type 'Namespace' is not assignable to type 'Module'.
!!! error TS2322: Types of property 'members' are incompatible.
!!! error TS2322: Type '(Class | Property)[]' is not assignable to type 'Class[]'.
!!! error TS2322: Type 'Class | Property' is not assignable to type 'Class'.
!!! error TS2322: Type 'Property' is not assignable to type 'Class'.
@@ -27,3 +27,21 @@ declare function h(x: Foo | Bar | Other): any;
h(x);
h({ a: '', b: '' })
interface CatDog { cat: any, dog: any }
interface ManBearPig { man: any, bear: any, pig: any }
interface Platypus { platypus: any }
type ExoticAnimal =
| CatDog
| ManBearPig
| Platypus;
declare function addToZoo(animal: ExoticAnimal): void;
addToZoo({ dog: "Barky McBarkface" });
addToZoo({ man: "Manny", bear: "Coffee" });
const manBeer = { man: "Manny", beer: "Coffee" };
addToZoo({ man: "Manny", beer: "Coffee" });
addToZoo(manBeer);