mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-06-13 01:33:08 -05:00
Merge pull request #30626 from Microsoft/discriminantFromIntersectionErrors
Better discriminant property errors on intersections
This commit is contained in:
@@ -12533,8 +12533,8 @@ namespace ts {
|
||||
|
||||
// Keep this up-to-date with the same logic within `getApparentTypeOfContextualType`, since they should behave similarly
|
||||
function findMatchingDiscriminantType(source: Type, target: Type) {
|
||||
if (target.flags & TypeFlags.Union) {
|
||||
const sourceProperties = getPropertiesOfObjectType(source);
|
||||
if (target.flags & TypeFlags.Union && source.flags & (TypeFlags.Intersection | TypeFlags.Object)) {
|
||||
const sourceProperties = getPropertiesOfType(source);
|
||||
if (sourceProperties) {
|
||||
const sourcePropertiesFiltered = findDiscriminantProperties(sourceProperties, target);
|
||||
if (sourcePropertiesFiltered) {
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
tests/cases/compiler/errorMessageOnIntersectionsWithDiscriminants01.ts(8,1): error TS2322: Type 'A' is not assignable to type 'B'.
|
||||
Type '{ test: true; } & { foo: 1; }' is not assignable to type 'B'.
|
||||
Type '{ test: true; } & { foo: 1; }' is not assignable to type '{ test: true; } & { bar: 1; }'.
|
||||
Property 'bar' is missing in type '{ test: true; } & { foo: 1; }' but required in type '{ bar: 1; }'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/errorMessageOnIntersectionsWithDiscriminants01.ts (1 errors) ====
|
||||
export type Common = { test: true } | { test: false };
|
||||
export type A = Common & { foo: 1 };
|
||||
export type B = Common & { bar: 1 };
|
||||
|
||||
declare const a: A;
|
||||
declare let b: B;
|
||||
|
||||
b = a;
|
||||
~
|
||||
!!! error TS2322: Type 'A' is not assignable to type 'B'.
|
||||
!!! error TS2322: Type '{ test: true; } & { foo: 1; }' is not assignable to type 'B'.
|
||||
!!! error TS2322: Type '{ test: true; } & { foo: 1; }' is not assignable to type '{ test: true; } & { bar: 1; }'.
|
||||
!!! error TS2322: Property 'bar' is missing in type '{ test: true; } & { foo: 1; }' but required in type '{ bar: 1; }'.
|
||||
!!! related TS2728 tests/cases/compiler/errorMessageOnIntersectionsWithDiscriminants01.ts:3:28: 'bar' is declared here.
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
=== tests/cases/compiler/errorMessageOnIntersectionsWithDiscriminants01.ts ===
|
||||
export type Common = { test: true } | { test: false };
|
||||
>Common : Symbol(Common, Decl(errorMessageOnIntersectionsWithDiscriminants01.ts, 0, 0))
|
||||
>test : Symbol(test, Decl(errorMessageOnIntersectionsWithDiscriminants01.ts, 0, 22))
|
||||
>test : Symbol(test, Decl(errorMessageOnIntersectionsWithDiscriminants01.ts, 0, 39))
|
||||
|
||||
export type A = Common & { foo: 1 };
|
||||
>A : Symbol(A, Decl(errorMessageOnIntersectionsWithDiscriminants01.ts, 0, 54))
|
||||
>Common : Symbol(Common, Decl(errorMessageOnIntersectionsWithDiscriminants01.ts, 0, 0))
|
||||
>foo : Symbol(foo, Decl(errorMessageOnIntersectionsWithDiscriminants01.ts, 1, 26))
|
||||
|
||||
export type B = Common & { bar: 1 };
|
||||
>B : Symbol(B, Decl(errorMessageOnIntersectionsWithDiscriminants01.ts, 1, 36))
|
||||
>Common : Symbol(Common, Decl(errorMessageOnIntersectionsWithDiscriminants01.ts, 0, 0))
|
||||
>bar : Symbol(bar, Decl(errorMessageOnIntersectionsWithDiscriminants01.ts, 2, 26))
|
||||
|
||||
declare const a: A;
|
||||
>a : Symbol(a, Decl(errorMessageOnIntersectionsWithDiscriminants01.ts, 4, 13))
|
||||
>A : Symbol(A, Decl(errorMessageOnIntersectionsWithDiscriminants01.ts, 0, 54))
|
||||
|
||||
declare let b: B;
|
||||
>b : Symbol(b, Decl(errorMessageOnIntersectionsWithDiscriminants01.ts, 5, 11))
|
||||
>B : Symbol(B, Decl(errorMessageOnIntersectionsWithDiscriminants01.ts, 1, 36))
|
||||
|
||||
b = a;
|
||||
>b : Symbol(b, Decl(errorMessageOnIntersectionsWithDiscriminants01.ts, 5, 11))
|
||||
>a : Symbol(a, Decl(errorMessageOnIntersectionsWithDiscriminants01.ts, 4, 13))
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
=== tests/cases/compiler/errorMessageOnIntersectionsWithDiscriminants01.ts ===
|
||||
export type Common = { test: true } | { test: false };
|
||||
>Common : Common
|
||||
>test : true
|
||||
>true : true
|
||||
>test : false
|
||||
>false : false
|
||||
|
||||
export type A = Common & { foo: 1 };
|
||||
>A : A
|
||||
>foo : 1
|
||||
|
||||
export type B = Common & { bar: 1 };
|
||||
>B : B
|
||||
>bar : 1
|
||||
|
||||
declare const a: A;
|
||||
>a : A
|
||||
|
||||
declare let b: B;
|
||||
>b : B
|
||||
|
||||
b = a;
|
||||
>b = a : A
|
||||
>b : B
|
||||
>a : A
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
// @noEmit: true
|
||||
|
||||
export type Common = { test: true } | { test: false };
|
||||
export type A = Common & { foo: 1 };
|
||||
export type B = Common & { bar: 1 };
|
||||
|
||||
declare const a: A;
|
||||
declare let b: B;
|
||||
|
||||
b = a;
|
||||
Reference in New Issue
Block a user