Merge pull request #14006 from Microsoft/better-discriminated-union-errors

Improve discriminated union error messages
This commit is contained in:
Nathan Shively-Sanders 2017-02-13 14:14:22 -08:00 committed by GitHub
commit ba8330cba6
4 changed files with 79 additions and 3 deletions

View File

@ -7783,16 +7783,36 @@ namespace ts {
if (target.flags & TypeFlags.Union && containsType(targetTypes, source)) {
return Ternary.True;
}
const len = targetTypes.length;
for (let i = 0; i < len; i++) {
const related = isRelatedTo(source, targetTypes[i], reportErrors && i === len - 1);
for (const type of targetTypes) {
const related = isRelatedTo(source, type, /*reportErrors*/ false);
if (related) {
return related;
}
}
if (reportErrors) {
const discriminantType = findMatchingDiscriminantType(source, target);
isRelatedTo(source, discriminantType || targetTypes[targetTypes.length - 1], /*reportErrors*/ true);
}
return Ternary.False;
}
function findMatchingDiscriminantType(source: Type, target: UnionOrIntersectionType) {
const sourceProperties = getPropertiesOfObjectType(source);
if (sourceProperties) {
for (const sourceProperty of sourceProperties) {
if (isDiscriminantProperty(target, sourceProperty.name)) {
const sourceType = getTypeOfSymbol(sourceProperty);
for (const type of target.types) {
const targetType = getTypeOfPropertyOfType(type, sourceProperty.name);
if (targetType && isRelatedTo(sourceType, targetType)) {
return type;
}
}
}
}
}
}
function typeRelatedToEachType(source: Type, target: UnionOrIntersectionType, reportErrors: boolean): Ternary {
let result = Ternary.True;
const targetTypes = target.types;

View File

@ -0,0 +1,23 @@
tests/cases/compiler/discriminatedUnionErrorMessage.ts(8,5): error TS2322: Type '{ kind: "sq"; x: number; y: number; }' is not assignable to type 'Shape'.
Type '{ kind: "sq"; x: number; y: number; }' is not assignable to type 'Square'.
Property 'size' is missing in type '{ kind: "sq"; x: number; y: number; }'.
==== tests/cases/compiler/discriminatedUnionErrorMessage.ts (1 errors) ====
type Square = { kind: "sq", size: number }
type Rectangle = { kind: "rt", x: number, y: number }
type Circle = { kind: "cr", radius: number }
type Shape =
| Square
| Rectangle
| Circle;
let shape: Shape = {
~~~~~
!!! error TS2322: Type '{ kind: "sq"; x: number; y: number; }' is not assignable to type 'Shape'.
!!! error TS2322: Type '{ kind: "sq"; x: number; y: number; }' is not assignable to type 'Square'.
!!! error TS2322: Property 'size' is missing in type '{ kind: "sq"; x: number; y: number; }'.
kind: "sq",
x: 12,
y: 13,
}

View File

@ -0,0 +1,21 @@
//// [discriminatedUnionErrorMessage.ts]
type Square = { kind: "sq", size: number }
type Rectangle = { kind: "rt", x: number, y: number }
type Circle = { kind: "cr", radius: number }
type Shape =
| Square
| Rectangle
| Circle;
let shape: Shape = {
kind: "sq",
x: 12,
y: 13,
}
//// [discriminatedUnionErrorMessage.js]
var shape = {
kind: "sq",
x: 12,
y: 13
};

View File

@ -0,0 +1,12 @@
type Square = { kind: "sq", size: number }
type Rectangle = { kind: "rt", x: number, y: number }
type Circle = { kind: "cr", radius: number }
type Shape =
| Square
| Rectangle
| Circle;
let shape: Shape = {
kind: "sq",
x: 12,
y: 13,
}