diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 0cd80de4a78de..929d67c0c3647 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -22627,12 +22627,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } let i = 0; for (const type of target.types) { - const targetType = getTypeOfPropertyOfType(type, propertyName); - if (targetType && related(getDiscriminatingType(), targetType)) { - discriminable[i] = discriminable[i] === undefined ? true : discriminable[i]; - } - else { - discriminable[i] = false; + if (discriminable[i] === undefined) { + const targetType = getTypeOfPropertyOfType(type, propertyName); + discriminable[i] = !!(targetType && related(getDiscriminatingType(), targetType)); } i++; } diff --git a/tests/baselines/reference/assignmentCompatWithDiscriminatedUnion.errors.txt b/tests/baselines/reference/assignmentCompatWithDiscriminatedUnion.errors.txt index 1479d824429a1..26632957ffa2a 100644 --- a/tests/baselines/reference/assignmentCompatWithDiscriminatedUnion.errors.txt +++ b/tests/baselines/reference/assignmentCompatWithDiscriminatedUnion.errors.txt @@ -6,10 +6,6 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithDiscriminatedUnion.ts(58,5): error TS2322: Type 'S' is not assignable to type 'T'. Property 'c' is missing in type 'S' but required in type '{ a: 2; b: 4 | 3; c: string; }'. tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithDiscriminatedUnion.ts(82,5): error TS2322: Type 'S' is not assignable to type 'T'. - Type 'S' is not assignable to type '{ a: N; b: N; c: 2; }'. - Types of property 'c' are incompatible. - Type 'N' is not assignable to type '2'. - Type '0' is not assignable to type '2'. ==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithDiscriminatedUnion.ts (3 errors) ==== @@ -107,10 +103,6 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme t = s; ~ !!! error TS2322: Type 'S' is not assignable to type 'T'. -!!! error TS2322: Type 'S' is not assignable to type '{ a: N; b: N; c: 2; }'. -!!! error TS2322: Types of property 'c' are incompatible. -!!! error TS2322: Type 'N' is not assignable to type '2'. -!!! error TS2322: Type '0' is not assignable to type '2'. } // https://github.com/Microsoft/TypeScript/issues/14865 diff --git a/tests/baselines/reference/excessPropertyCheckWithMultipleDiscriminants.errors.txt b/tests/baselines/reference/excessPropertyCheckWithMultipleDiscriminants.errors.txt index 62f17936146a4..38ddb54475f8a 100644 --- a/tests/baselines/reference/excessPropertyCheckWithMultipleDiscriminants.errors.txt +++ b/tests/baselines/reference/excessPropertyCheckWithMultipleDiscriminants.errors.txt @@ -1,7 +1,7 @@ tests/cases/compiler/excessPropertyCheckWithMultipleDiscriminants.ts(30,5): error TS2322: Type '{ type: "number"; value: number; multipleOf: number; format: string; }' is not assignable to type 'Primitive'. Object literal may only specify known properties, and 'multipleOf' does not exist in type 'Float'. -tests/cases/compiler/excessPropertyCheckWithMultipleDiscriminants.ts(41,5): error TS2322: Type '{ p1: "left"; p2: false; p3: number; p4: string; }' is not assignable to type 'DisjointDiscriminants'. - Object literal may only specify known properties, and 'p3' does not exist in type '{ p1: "left"; p2: boolean; }'. +tests/cases/compiler/excessPropertyCheckWithMultipleDiscriminants.ts(42,5): error TS2322: Type '{ p1: "left"; p2: false; p3: number; p4: string; }' is not assignable to type 'DisjointDiscriminants'. + Object literal may only specify known properties, and 'p4' does not exist in type '{ p1: "left"; p2: true; p3: number; } | { p1: "left"; p2: boolean; }'. tests/cases/compiler/excessPropertyCheckWithMultipleDiscriminants.ts(50,5): error TS2322: Type '{ p1: "left"; p2: true; p3: number; p4: string; }' is not assignable to type 'DisjointDiscriminants'. Object literal may only specify known properties, and 'p4' does not exist in type '{ p1: "left"; p2: true; p3: number; } | { p1: "left"; p2: boolean; }'. tests/cases/compiler/excessPropertyCheckWithMultipleDiscriminants.ts(57,5): error TS2322: Type '{ p1: "right"; p2: false; p3: number; p4: string; }' is not assignable to type 'DisjointDiscriminants'. @@ -59,10 +59,10 @@ tests/cases/compiler/excessPropertyCheckWithMultipleDiscriminants.ts(136,5): err p1: 'left', p2: false, p3: 42, + p4: "hello" ~~ !!! error TS2322: Type '{ p1: "left"; p2: false; p3: number; p4: string; }' is not assignable to type 'DisjointDiscriminants'. -!!! error TS2322: Object literal may only specify known properties, and 'p3' does not exist in type '{ p1: "left"; p2: boolean; }'. - p4: "hello" +!!! error TS2322: Object literal may only specify known properties, and 'p4' does not exist in type '{ p1: "left"; p2: true; p3: number; } | { p1: "left"; p2: boolean; }'. }; // This has excess error because variant two is not applicable. diff --git a/tests/baselines/reference/objectLiteralNormalization.errors.txt b/tests/baselines/reference/objectLiteralNormalization.errors.txt index a6ffc718f913c..25c20b5c23d31 100644 --- a/tests/baselines/reference/objectLiteralNormalization.errors.txt +++ b/tests/baselines/reference/objectLiteralNormalization.errors.txt @@ -5,9 +5,8 @@ tests/cases/conformance/expressions/objectLiterals/objectLiteralNormalization.ts tests/cases/conformance/expressions/objectLiterals/objectLiteralNormalization.ts(9,1): error TS2322: Type '{ c: true; }' is not assignable to type '{ a: number; b?: undefined; c?: undefined; } | { a: number; b: string; c?: undefined; } | { a: number; b: string; c: boolean; }'. Type '{ c: true; }' is missing the following properties from type '{ a: number; b: string; c: boolean; }': a, b tests/cases/conformance/expressions/objectLiterals/objectLiteralNormalization.ts(17,1): error TS2322: Type '{ a: string; b: number; }' is not assignable to type '{ a: number; b: number; } | { a: string; b?: undefined; } | { a?: undefined; b?: undefined; }'. - Type '{ a: string; b: number; }' is not assignable to type '{ a?: undefined; b?: undefined; }'. - Types of property 'a' are incompatible. - Type 'string' is not assignable to type 'undefined'. + Types of property 'b' are incompatible. + Type 'number' is not assignable to type 'undefined'. tests/cases/conformance/expressions/objectLiterals/objectLiteralNormalization.ts(18,1): error TS2322: Type '{ a: number; }' is not assignable to type '{ a: number; b: number; } | { a: string; b?: undefined; } | { a?: undefined; b?: undefined; }'. Property 'b' is missing in type '{ a: number; }' but required in type '{ a: number; b: number; }'. tests/cases/conformance/expressions/objectLiterals/objectLiteralNormalization.ts(48,20): error TS2322: Type '2' is not assignable to type '1'. @@ -44,9 +43,8 @@ tests/cases/conformance/expressions/objectLiterals/objectLiteralNormalization.ts a2 = { a: "def", b: 20 }; // Error ~~ !!! error TS2322: Type '{ a: string; b: number; }' is not assignable to type '{ a: number; b: number; } | { a: string; b?: undefined; } | { a?: undefined; b?: undefined; }'. -!!! error TS2322: Type '{ a: string; b: number; }' is not assignable to type '{ a?: undefined; b?: undefined; }'. -!!! error TS2322: Types of property 'a' are incompatible. -!!! error TS2322: Type 'string' is not assignable to type 'undefined'. +!!! error TS2322: Types of property 'b' are incompatible. +!!! error TS2322: Type 'number' is not assignable to type 'undefined'. a2 = { a: 1 }; // Error ~~ !!! error TS2322: Type '{ a: number; }' is not assignable to type '{ a: number; b: number; } | { a: string; b?: undefined; } | { a?: undefined; b?: undefined; }'. diff --git a/tests/cases/fourslash/completionsUnionStringLiteralProperty.ts b/tests/cases/fourslash/completionsUnionStringLiteralProperty.ts new file mode 100644 index 0000000000000..a3439d10d7efa --- /dev/null +++ b/tests/cases/fourslash/completionsUnionStringLiteralProperty.ts @@ -0,0 +1,9 @@ +/// + +//// type Foo = { a: 0, b: 'x' } | { a: 0, b: 'y' } | { a: 1, b: 'z' }; +//// const foo: Foo = { a: 0, b: '/*1*/' } +//// +//// type Bar = { a: 0, b: 'fx' } | { a: 0, b: 'fy' } | { a: 1, b: 'fz' }; +//// const bar: Bar = { a: 0, b: 'f/*2*/' } +verify.completions({ marker: "1", triggerCharacter: "'", includes: [ "x", "y" ], excludes: [ "z" ] }); +verify.completions({ marker: "2", triggerCharacter: "'", includes: [ "fx", "fy" ], excludes: [ "fz" ] }); \ No newline at end of file