Skip to content

What if every type with differing properties was a discriminant? #48501

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23074,7 +23074,7 @@ namespace ts {
if (prop && getCheckFlags(prop) & CheckFlags.SyntheticProperty) {
if ((prop as TransientSymbol).isDiscriminantProperty === undefined) {
(prop as TransientSymbol).isDiscriminantProperty =
((prop as TransientSymbol).checkFlags & CheckFlags.Discriminant) === CheckFlags.Discriminant &&
!!((prop as TransientSymbol).checkFlags & CheckFlags.Discriminant) &&
!isGenericType(getTypeOfSymbol(prop));
}
return !!(prop as TransientSymbol).isDiscriminantProperty;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,12 @@ foo2({
>method : Symbol(method, Decl(contextualTypeShouldBeLiteral.ts, 40, 18))

this;
>this : Symbol(Y2, Decl(contextualTypeShouldBeLiteral.ts, 28, 1))

this.value;
>this.value : Symbol(value, Decl(contextualTypeShouldBeLiteral.ts, 25, 15), Decl(contextualTypeShouldBeLiteral.ts, 31, 15))
>value : Symbol(value, Decl(contextualTypeShouldBeLiteral.ts, 25, 15), Decl(contextualTypeShouldBeLiteral.ts, 31, 15))
>this.value : Symbol(Y2.value, Decl(contextualTypeShouldBeLiteral.ts, 31, 15))
>this : Symbol(Y2, Decl(contextualTypeShouldBeLiteral.ts, 28, 1))
>value : Symbol(Y2.value, Decl(contextualTypeShouldBeLiteral.ts, 31, 15))
}
});

Expand Down
8 changes: 4 additions & 4 deletions tests/baselines/reference/contextualTypeShouldBeLiteral.types
Original file line number Diff line number Diff line change
Expand Up @@ -99,12 +99,12 @@ foo2({
>method : () => void

this;
>this : X2 | Y2
>this : Y2

this.value;
>this.value : string
>this : X2 | Y2
>value : string
>this.value : "none" | "done"
>this : Y2
>value : "none" | "done"
}
});

Expand Down
Original file line number Diff line number Diff line change
@@ -1,35 +1,20 @@
tests/cases/conformance/types/union/contextualTypeWithUnionTypeObjectLiteral.ts(14,5): error TS2322: Type '{ prop: string | number; }' is not assignable to type '{ prop: string; } | { prop: number; }'.
Type '{ prop: string | number; }' is not assignable to type '{ prop: number; }'.
Types of property 'prop' are incompatible.
Type 'string | number' is not assignable to type 'number'.
Type 'string' is not assignable to type 'number'.
tests/cases/conformance/types/union/contextualTypeWithUnionTypeObjectLiteral.ts(20,5): error TS2322: Type '{ prop: string | number; }' is not assignable to type '{ prop: string; anotherP: string; } | { prop: number; }'.
Type '{ prop: string | number; }' is not assignable to type '{ prop: number; }'.
Types of property 'prop' are incompatible.
Type 'string | number' is not assignable to type 'number'.
Type 'string' is not assignable to type 'number'.
tests/cases/conformance/types/union/contextualTypeWithUnionTypeObjectLiteral.ts(21,5): error TS2322: Type '{ prop: string | number; anotherP: string; }' is not assignable to type '{ prop: string; anotherP: string; } | { prop: number; }'.
Type '{ prop: string | number; anotherP: string; }' is not assignable to type '{ prop: string; anotherP: string; }'.
Types of property 'prop' are incompatible.
Type 'string | number' is not assignable to type 'string'.
Type 'number' is not assignable to type 'string'.
tests/cases/conformance/types/union/contextualTypeWithUnionTypeObjectLiteral.ts(25,5): error TS2322: Type '{ prop: string | number; anotherP: string; }' is not assignable to type '{ prop: string; anotherP: string; } | { prop: number; anotherP1: number; }'.
Type '{ prop: string | number; anotherP: string; }' is not assignable to type '{ prop: string; anotherP: string; }'.
Types of property 'prop' are incompatible.
Type 'string | number' is not assignable to type 'string'.
Type 'number' is not assignable to type 'string'.
tests/cases/conformance/types/union/contextualTypeWithUnionTypeObjectLiteral.ts(29,5): error TS2322: Type '{ prop: string | number; anotherP: string; anotherP1: number; }' is not assignable to type '{ prop: string; anotherP: string; } | { prop: number; anotherP1: number; }'.
Type '{ prop: string | number; anotherP: string; anotherP1: number; }' is not assignable to type '{ prop: number; anotherP1: number; }'.
Types of property 'prop' are incompatible.
Type 'string | number' is not assignable to type 'number'.
Type 'string' is not assignable to type 'number'.
tests/cases/conformance/types/union/contextualTypeWithUnionTypeObjectLiteral.ts(58,5): error TS2322: Type '(a: string, b: number) => string | number' is not assignable to type '((a: string, b: number) => string) | ((a: string, b: number) => number)'.
Type '(a: string, b: number) => string | number' is not assignable to type '(a: string, b: number) => string'.
Type 'string | number' is not assignable to type 'string'.
Type 'number' is not assignable to type 'string'.


==== tests/cases/conformance/types/union/contextualTypeWithUnionTypeObjectLiteral.ts (6 errors) ====
==== tests/cases/conformance/types/union/contextualTypeWithUnionTypeObjectLiteral.ts (3 errors) ====
var str: string;
var num: number;
var strOrNumber: string | number = str || num;
Expand All @@ -44,12 +29,6 @@ tests/cases/conformance/types/union/contextualTypeWithUnionTypeObjectLiteral.ts(
// In case of objStrOrNum3, the S is not union Type but object Literal so we go to next step.
// Since T is union Type we only allow the assignment of either object with property of type string or object with property of type number but do not allow object with property of type string | number
var objStrOrNum3: { prop: string } | { prop: number } = {
~~~~~~~~~~~~
!!! error TS2322: Type '{ prop: string | number; }' is not assignable to type '{ prop: string; } | { prop: number; }'.
!!! error TS2322: Type '{ prop: string | number; }' is not assignable to type '{ prop: number; }'.
!!! error TS2322: Types of property 'prop' are incompatible.
!!! error TS2322: Type 'string | number' is not assignable to type 'number'.
!!! error TS2322: Type 'string' is not assignable to type 'number'.
prop: strOrNumber
};
var objStrOrNum4: { prop: string | number } = {
Expand All @@ -63,12 +42,6 @@ tests/cases/conformance/types/union/contextualTypeWithUnionTypeObjectLiteral.ts(
!!! error TS2322: Type 'string | number' is not assignable to type 'number'.
!!! error TS2322: Type 'string' is not assignable to type 'number'.
var objStrOrNum6: { prop: string; anotherP: string; } | { prop: number } = {
~~~~~~~~~~~~
!!! error TS2322: Type '{ prop: string | number; anotherP: string; }' is not assignable to type '{ prop: string; anotherP: string; } | { prop: number; }'.
!!! error TS2322: Type '{ prop: string | number; anotherP: string; }' is not assignable to type '{ prop: string; anotherP: string; }'.
!!! error TS2322: Types of property 'prop' are incompatible.
!!! error TS2322: Type 'string | number' is not assignable to type 'string'.
!!! error TS2322: Type 'number' is not assignable to type 'string'.
prop: strOrNumber,
anotherP: str
};
Expand All @@ -83,12 +56,6 @@ tests/cases/conformance/types/union/contextualTypeWithUnionTypeObjectLiteral.ts(
anotherP: str
};
var objStrOrNum8: { prop: string; anotherP: string; } | { prop: number; anotherP1: number } = {
~~~~~~~~~~~~
!!! error TS2322: Type '{ prop: string | number; anotherP: string; anotherP1: number; }' is not assignable to type '{ prop: string; anotherP: string; } | { prop: number; anotherP1: number; }'.
!!! error TS2322: Type '{ prop: string | number; anotherP: string; anotherP1: number; }' is not assignable to type '{ prop: number; anotherP1: number; }'.
!!! error TS2322: Types of property 'prop' are incompatible.
!!! error TS2322: Type 'string | number' is not assignable to type 'number'.
!!! error TS2322: Type 'string' is not assignable to type 'number'.
prop: strOrNumber,
anotherP: str,
anotherP1: num
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ tests/cases/conformance/types/union/discriminatedUnionTypes2.ts(27,30): error TS
Object literal may only specify known properties, and 'c' does not exist in type '{ a: null; b: string; }'.
tests/cases/conformance/types/union/discriminatedUnionTypes2.ts(32,11): error TS2339: Property 'b' does not exist on type '{ a: 0; b: string; } | { a: T; c: number; }'.
Property 'b' does not exist on type '{ a: T; c: number; }'.
tests/cases/conformance/types/union/discriminatedUnionTypes2.ts(132,11): error TS2339: Property 'value' does not exist on type 'never'.


==== tests/cases/conformance/types/union/discriminatedUnionTypes2.ts (2 errors) ====
==== tests/cases/conformance/types/union/discriminatedUnionTypes2.ts (3 errors) ====
function f10(x : { kind: false, a: string } | { kind: true, b: string } | { kind: string, c: string }) {
if (x.kind === false) {
x.a;
Expand Down Expand Up @@ -143,6 +144,8 @@ tests/cases/conformance/types/union/discriminatedUnionTypes2.ts(32,11): error TS
}
else {
x.value; // number
~~~~~
!!! error TS2339: Property 'value' does not exist on type 'never'.
}
}

Expand Down
2 changes: 0 additions & 2 deletions tests/baselines/reference/discriminatedUnionTypes2.symbols
Original file line number Diff line number Diff line change
Expand Up @@ -367,9 +367,7 @@ function foo1(x: RuntimeValue & { type: 'number' }) {
}
else {
x.value; // number
>x.value : Symbol(value, Decl(discriminatedUnionTypes2.ts, 122, 23))
>x : Symbol(x, Decl(discriminatedUnionTypes2.ts, 126, 14))
>value : Symbol(value, Decl(discriminatedUnionTypes2.ts, 122, 23))
}
}

Expand Down
6 changes: 3 additions & 3 deletions tests/baselines/reference/discriminatedUnionTypes2.types
Original file line number Diff line number Diff line change
Expand Up @@ -380,9 +380,9 @@ function foo1(x: RuntimeValue & { type: 'number' }) {
}
else {
x.value; // number
>x.value : number
>x : { type: "number"; value: number; } & { type: "number"; }
>value : number
>x.value : any
>x : never
>value : any
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ tests/cases/compiler/errorsOnUnionsOfOverlappingObjects01.ts(18,3): error TS2345
tests/cases/compiler/errorsOnUnionsOfOverlappingObjects01.ts(19,12): error TS2322: 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(29,12): error TS2322: Type 'string' is not assignable to type 'number'.
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'.
Expand All @@ -15,7 +16,7 @@ tests/cases/compiler/errorsOnUnionsOfOverlappingObjects01.ts(47,10): error TS234
Type '{ man: string; beer: string; }' is missing the following properties from type 'ManBearPig': bear, pig


==== tests/cases/compiler/errorsOnUnionsOfOverlappingObjects01.ts (7 errors) ====
==== tests/cases/compiler/errorsOnUnionsOfOverlappingObjects01.ts (8 errors) ====
interface Foo {
a: string;
b: number;
Expand Down Expand Up @@ -55,6 +56,8 @@ tests/cases/compiler/errorsOnUnionsOfOverlappingObjects01.ts(47,10): error TS234

h(x);
h({ a: '', b: '' })
~
!!! error TS2322: Type 'string' is not assignable to type 'number'.

interface CatDog { cat: any, dog: any }
interface ManBearPig { man: any, bear: any, pig: any }
Expand Down
22 changes: 7 additions & 15 deletions tests/baselines/reference/excessPropertyCheckWithUnions.errors.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
tests/cases/compiler/excessPropertyCheckWithUnions.ts(10,30): error TS2322: Type '{ tag: "T"; a1: string; }' is not assignable to type 'ADT'.
Object literal may only specify known properties, and 'a1' does not exist in type '{ tag: "T"; }'.
tests/cases/compiler/excessPropertyCheckWithUnions.ts(11,21): error TS2322: Type '{ tag: "A"; d20: number; }' is not assignable to type 'ADT'.
Object literal may only specify known properties, and 'd20' does not exist in type '{ tag: "A"; a1: string; }'.
tests/cases/compiler/excessPropertyCheckWithUnions.ts(11,1): error TS2322: Type '{ tag: "A"; d20: 12; }' is not assignable to type 'ADT'.
Property 'a1' is missing in type '{ tag: "A"; d20: 12; }' but required in type '{ tag: "A"; a1: string; }'.
tests/cases/compiler/excessPropertyCheckWithUnions.ts(12,1): error TS2322: Type '{ tag: "D"; }' is not assignable to type 'ADT'.
Property 'd20' is missing in type '{ tag: "D"; }' but required in type '{ tag: "D"; d20: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20; }'.
tests/cases/compiler/excessPropertyCheckWithUnions.ts(33,28): error TS2322: Type '{ tag: "A"; x: string; extra: number; }' is not assignable to type 'Ambiguous'.
Expand All @@ -20,18 +20,14 @@ tests/cases/compiler/excessPropertyCheckWithUnions.ts(49,35): error TS2322: Type
Object literal may only specify known properties, and 'second' does not exist in type '{ a: 1; b: 1; first: string; }'.
tests/cases/compiler/excessPropertyCheckWithUnions.ts(50,35): error TS2322: Type '{ a: 1; b: 1; first: string; third: string; }' is not assignable to type 'Overlapping'.
Object literal may only specify known properties, and 'third' does not exist in type '{ a: 1; b: 1; first: string; }'.
tests/cases/compiler/excessPropertyCheckWithUnions.ts(66,9): error TS2322: Type '{ kind: "A"; n: { a: string; b: string; }; }' is not assignable to type 'AB'.
Types of property 'n' are incompatible.
Type '{ a: string; b: string; }' is not assignable to type 'AN'.
Object literal may only specify known properties, and 'b' does not exist in type 'AN'.
tests/cases/compiler/excessPropertyCheckWithUnions.ts(87,5): error TS2322: Type '{ tag: "button"; type: "submit"; href: string; }' is not assignable to type 'Union'.
Object literal may only specify known properties, and 'href' does not exist in type 'Button'.
tests/cases/compiler/excessPropertyCheckWithUnions.ts(108,5): error TS2322: Type 'string' is not assignable to type 'IValue'.
tests/cases/compiler/excessPropertyCheckWithUnions.ts(113,67): error TS2322: Type 'string' is not assignable to type 'number'.
tests/cases/compiler/excessPropertyCheckWithUnions.ts(114,63): error TS2322: Type 'string' is not assignable to type 'number'.


==== tests/cases/compiler/excessPropertyCheckWithUnions.ts (14 errors) ====
==== tests/cases/compiler/excessPropertyCheckWithUnions.ts (13 errors) ====
type ADT = {
tag: "A",
a1: string
Expand All @@ -46,9 +42,10 @@ tests/cases/compiler/excessPropertyCheckWithUnions.ts(114,63): error TS2322: Typ
!!! error TS2322: Type '{ tag: "T"; a1: string; }' is not assignable to type 'ADT'.
!!! error TS2322: Object literal may only specify known properties, and 'a1' does not exist in type '{ tag: "T"; }'.
wrong = { tag: "A", d20: 12 }
~~~~~~~
!!! error TS2322: Type '{ tag: "A"; d20: number; }' is not assignable to type 'ADT'.
!!! error TS2322: Object literal may only specify known properties, and 'd20' does not exist in type '{ tag: "A"; a1: string; }'.
~~~~~
!!! error TS2322: Type '{ tag: "A"; d20: 12; }' is not assignable to type 'ADT'.
!!! error TS2322: Property 'a1' is missing in type '{ tag: "A"; d20: 12; }' but required in type '{ tag: "A"; a1: string; }'.
!!! related TS2728 tests/cases/compiler/excessPropertyCheckWithUnions.ts:3:5: 'a1' is declared here.
wrong = { tag: "D" }
~~~~~
!!! error TS2322: Type '{ tag: "D"; }' is not assignable to type 'ADT'.
Expand Down Expand Up @@ -130,11 +127,6 @@ tests/cases/compiler/excessPropertyCheckWithUnions.ts(114,63): error TS2322: Typ
n: {
a: "a",
b: "b", // excess -- kind: "A"
~~~~~~
!!! error TS2322: Type '{ kind: "A"; n: { a: string; b: string; }; }' is not assignable to type 'AB'.
!!! error TS2322: Types of property 'n' are incompatible.
!!! error TS2322: Type '{ a: string; b: string; }' is not assignable to type 'AN'.
!!! error TS2322: Object literal may only specify known properties, and 'b' does not exist in type 'AN'.
}
}
const abac: AB = {
Expand Down
6 changes: 3 additions & 3 deletions tests/baselines/reference/excessPropertyCheckWithUnions.types
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@ let wrong: ADT = { tag: "T", a1: "extra" }
>"extra" : "extra"

wrong = { tag: "A", d20: 12 }
>wrong = { tag: "A", d20: 12 } : { tag: "A"; d20: number; }
>wrong = { tag: "A", d20: 12 } : { tag: "A"; d20: 12; }
>wrong : ADT
>{ tag: "A", d20: 12 } : { tag: "A"; d20: number; }
>{ tag: "A", d20: 12 } : { tag: "A"; d20: 12; }
>tag : "A"
>"A" : "A"
>d20 : number
>d20 : 12
>12 : 12

wrong = { tag: "D" }
Expand Down
20 changes: 12 additions & 8 deletions tests/baselines/reference/mappedTypeIndexedAccess.errors.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
tests/cases/compiler/mappedTypeIndexedAccess.ts(18,5): error TS2322: Type '{ key: "foo"; value: number; }' is not assignable to type 'Pair<FooBar>'.
Types of property 'value' are incompatible.
Type 'number' is not assignable to type 'string'.
Type '{ key: "foo"; value: number; }' is not assignable to type '{ key: "bar"; value: number; }'.
Types of property 'key' are incompatible.
Type '"foo"' is not assignable to type '"bar"'.
tests/cases/compiler/mappedTypeIndexedAccess.ts(24,5): error TS2322: Type '{ key: "foo"; value: number; }' is not assignable to type '{ key: "foo"; value: string; } | { key: "bar"; value: number; }'.
Types of property 'value' are incompatible.
Type 'number' is not assignable to type 'string'.
Type '{ key: "foo"; value: number; }' is not assignable to type '{ key: "bar"; value: number; }'.
Types of property 'key' are incompatible.
Type '"foo"' is not assignable to type '"bar"'.


==== tests/cases/compiler/mappedTypeIndexedAccess.ts (2 errors) ====
Expand All @@ -27,8 +29,9 @@ tests/cases/compiler/mappedTypeIndexedAccess.ts(24,5): error TS2322: Type '{ key
let pair1: Pair<FooBar> = {
~~~~~
!!! error TS2322: Type '{ key: "foo"; value: number; }' is not assignable to type 'Pair<FooBar>'.
!!! error TS2322: Types of property 'value' are incompatible.
!!! error TS2322: Type 'number' is not assignable to type 'string'.
!!! error TS2322: Type '{ key: "foo"; value: number; }' is not assignable to type '{ key: "bar"; value: number; }'.
!!! error TS2322: Types of property 'key' are incompatible.
!!! error TS2322: Type '"foo"' is not assignable to type '"bar"'.
key: "foo",
value: 3
};
Expand All @@ -37,8 +40,9 @@ tests/cases/compiler/mappedTypeIndexedAccess.ts(24,5): error TS2322: Type '{ key
let pair2: Pairs<FooBar>[keyof FooBar] = {
~~~~~
!!! error TS2322: Type '{ key: "foo"; value: number; }' is not assignable to type '{ key: "foo"; value: string; } | { key: "bar"; value: number; }'.
!!! error TS2322: Types of property 'value' are incompatible.
!!! error TS2322: Type 'number' is not assignable to type 'string'.
!!! error TS2322: Type '{ key: "foo"; value: number; }' is not assignable to type '{ key: "bar"; value: number; }'.
!!! error TS2322: Types of property 'key' are incompatible.
!!! error TS2322: Type '"foo"' is not assignable to type '"bar"'.
key: "foo",
value: 3
};
Expand Down
2 changes: 1 addition & 1 deletion tests/baselines/reference/narrowingDestructuring.types
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,6 @@ function farr<T extends [number, string, string] | [string, number, number]>(x:
const [head, ...tail] = x;
>head : "number"
>tail : (string | number)[]
>x : [number, string, string] | [string, number, number]
>x : [string, number, number]
}
}
Loading