Skip to content

Commit

Permalink
Discriminate types with divergent read/write property types (microsof…
Browse files Browse the repository at this point in the history
  • Loading branch information
Andarist authored and snovader committed Sep 23, 2023
1 parent 4976f4a commit 6a011b5
Show file tree
Hide file tree
Showing 25 changed files with 2,086 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14389,7 +14389,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
if (writeTypes || writeType !== type) {
writeTypes = append(!writeTypes ? propTypes.slice() : writeTypes, writeType);
}
else if (type !== firstType) {
if (type !== firstType) {
checkFlags |= CheckFlags.HasNonUniformType;
}
if (isLiteralType(type) || isPatternLiteralType(type)) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
//// [tests/cases/compiler/discriminateWithDivergentAccessors1.ts] ////

=== discriminateWithDivergentAccessors1.ts ===
type WeirdoBox<T> =
>WeirdoBox : Symbol(WeirdoBox, Decl(discriminateWithDivergentAccessors1.ts, 0, 0))
>T : Symbol(T, Decl(discriminateWithDivergentAccessors1.ts, 0, 15))

| { get done(): false; set done(v: T | null) }
>done : Symbol(done, Decl(discriminateWithDivergentAccessors1.ts, 1, 5), Decl(discriminateWithDivergentAccessors1.ts, 1, 24))
>done : Symbol(done, Decl(discriminateWithDivergentAccessors1.ts, 1, 5), Decl(discriminateWithDivergentAccessors1.ts, 1, 24))
>v : Symbol(v, Decl(discriminateWithDivergentAccessors1.ts, 1, 34))
>T : Symbol(T, Decl(discriminateWithDivergentAccessors1.ts, 0, 15))

| { get done(): true; set done(v: T | null); value: T };
>done : Symbol(done, Decl(discriminateWithDivergentAccessors1.ts, 2, 5), Decl(discriminateWithDivergentAccessors1.ts, 2, 23))
>done : Symbol(done, Decl(discriminateWithDivergentAccessors1.ts, 2, 5), Decl(discriminateWithDivergentAccessors1.ts, 2, 23))
>v : Symbol(v, Decl(discriminateWithDivergentAccessors1.ts, 2, 33))
>T : Symbol(T, Decl(discriminateWithDivergentAccessors1.ts, 0, 15))
>value : Symbol(value, Decl(discriminateWithDivergentAccessors1.ts, 2, 46))
>T : Symbol(T, Decl(discriminateWithDivergentAccessors1.ts, 0, 15))

declare const weirdoBox: WeirdoBox<number>;
>weirdoBox : Symbol(weirdoBox, Decl(discriminateWithDivergentAccessors1.ts, 4, 13))
>WeirdoBox : Symbol(WeirdoBox, Decl(discriminateWithDivergentAccessors1.ts, 0, 0))

if (weirdoBox.done) {
>weirdoBox.done : Symbol(done, Decl(discriminateWithDivergentAccessors1.ts, 1, 5), Decl(discriminateWithDivergentAccessors1.ts, 1, 24), Decl(discriminateWithDivergentAccessors1.ts, 2, 5), Decl(discriminateWithDivergentAccessors1.ts, 2, 23))
>weirdoBox : Symbol(weirdoBox, Decl(discriminateWithDivergentAccessors1.ts, 4, 13))
>done : Symbol(done, Decl(discriminateWithDivergentAccessors1.ts, 1, 5), Decl(discriminateWithDivergentAccessors1.ts, 1, 24), Decl(discriminateWithDivergentAccessors1.ts, 2, 5), Decl(discriminateWithDivergentAccessors1.ts, 2, 23))

weirdoBox.value;
>weirdoBox.value : Symbol(value, Decl(discriminateWithDivergentAccessors1.ts, 2, 46))
>weirdoBox : Symbol(weirdoBox, Decl(discriminateWithDivergentAccessors1.ts, 4, 13))
>value : Symbol(value, Decl(discriminateWithDivergentAccessors1.ts, 2, 46))
}

type WeirdoBox2<T> =
>WeirdoBox2 : Symbol(WeirdoBox2, Decl(discriminateWithDivergentAccessors1.ts, 8, 1))
>T : Symbol(T, Decl(discriminateWithDivergentAccessors1.ts, 10, 16))

| { get done(): false; set done(v: T | null) }
>done : Symbol(done, Decl(discriminateWithDivergentAccessors1.ts, 11, 5), Decl(discriminateWithDivergentAccessors1.ts, 11, 24))
>done : Symbol(done, Decl(discriminateWithDivergentAccessors1.ts, 11, 5), Decl(discriminateWithDivergentAccessors1.ts, 11, 24))
>v : Symbol(v, Decl(discriminateWithDivergentAccessors1.ts, 11, 34))
>T : Symbol(T, Decl(discriminateWithDivergentAccessors1.ts, 10, 16))

| { get done(): true; set done(v: T | null); value: T }
>done : Symbol(done, Decl(discriminateWithDivergentAccessors1.ts, 12, 5), Decl(discriminateWithDivergentAccessors1.ts, 12, 23))
>done : Symbol(done, Decl(discriminateWithDivergentAccessors1.ts, 12, 5), Decl(discriminateWithDivergentAccessors1.ts, 12, 23))
>v : Symbol(v, Decl(discriminateWithDivergentAccessors1.ts, 12, 33))
>T : Symbol(T, Decl(discriminateWithDivergentAccessors1.ts, 10, 16))
>value : Symbol(value, Decl(discriminateWithDivergentAccessors1.ts, 12, 46))
>T : Symbol(T, Decl(discriminateWithDivergentAccessors1.ts, 10, 16))

| { get done(): true; set done(v: T | null | undefined); value: number };
>done : Symbol(done, Decl(discriminateWithDivergentAccessors1.ts, 13, 5), Decl(discriminateWithDivergentAccessors1.ts, 13, 23))
>done : Symbol(done, Decl(discriminateWithDivergentAccessors1.ts, 13, 5), Decl(discriminateWithDivergentAccessors1.ts, 13, 23))
>v : Symbol(v, Decl(discriminateWithDivergentAccessors1.ts, 13, 33))
>T : Symbol(T, Decl(discriminateWithDivergentAccessors1.ts, 10, 16))
>value : Symbol(value, Decl(discriminateWithDivergentAccessors1.ts, 13, 58))

declare const weirdoBox2: WeirdoBox2<string>;
>weirdoBox2 : Symbol(weirdoBox2, Decl(discriminateWithDivergentAccessors1.ts, 15, 13))
>WeirdoBox2 : Symbol(WeirdoBox2, Decl(discriminateWithDivergentAccessors1.ts, 8, 1))

if (weirdoBox2.done) {
>weirdoBox2.done : Symbol(done, Decl(discriminateWithDivergentAccessors1.ts, 11, 5), Decl(discriminateWithDivergentAccessors1.ts, 11, 24), Decl(discriminateWithDivergentAccessors1.ts, 12, 5), Decl(discriminateWithDivergentAccessors1.ts, 12, 23), Decl(discriminateWithDivergentAccessors1.ts, 13, 5) ... and 1 more)
>weirdoBox2 : Symbol(weirdoBox2, Decl(discriminateWithDivergentAccessors1.ts, 15, 13))
>done : Symbol(done, Decl(discriminateWithDivergentAccessors1.ts, 11, 5), Decl(discriminateWithDivergentAccessors1.ts, 11, 24), Decl(discriminateWithDivergentAccessors1.ts, 12, 5), Decl(discriminateWithDivergentAccessors1.ts, 12, 23), Decl(discriminateWithDivergentAccessors1.ts, 13, 5) ... and 1 more)

weirdoBox2.value;
>weirdoBox2.value : Symbol(value, Decl(discriminateWithDivergentAccessors1.ts, 12, 46), Decl(discriminateWithDivergentAccessors1.ts, 13, 58))
>weirdoBox2 : Symbol(weirdoBox2, Decl(discriminateWithDivergentAccessors1.ts, 15, 13))
>value : Symbol(value, Decl(discriminateWithDivergentAccessors1.ts, 12, 46), Decl(discriminateWithDivergentAccessors1.ts, 13, 58))
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
//// [tests/cases/compiler/discriminateWithDivergentAccessors1.ts] ////

=== discriminateWithDivergentAccessors1.ts ===
type WeirdoBox<T> =
>WeirdoBox : WeirdoBox<T>

| { get done(): false; set done(v: T | null) }
>done : false
>false : false
>done : false
>v : T | null

| { get done(): true; set done(v: T | null); value: T };
>done : true
>true : true
>done : true
>v : T | null
>value : T

declare const weirdoBox: WeirdoBox<number>;
>weirdoBox : WeirdoBox<number>

if (weirdoBox.done) {
>weirdoBox.done : boolean
>weirdoBox : WeirdoBox<number>
>done : boolean

weirdoBox.value;
>weirdoBox.value : number
>weirdoBox : { done: true; value: number; }
>value : number
}

type WeirdoBox2<T> =
>WeirdoBox2 : WeirdoBox2<T>

| { get done(): false; set done(v: T | null) }
>done : false
>false : false
>done : false
>v : T | null

| { get done(): true; set done(v: T | null); value: T }
>done : true
>true : true
>done : true
>v : T | null
>value : T

| { get done(): true; set done(v: T | null | undefined); value: number };
>done : true
>true : true
>done : true
>v : T | null | undefined
>value : number

declare const weirdoBox2: WeirdoBox2<string>;
>weirdoBox2 : WeirdoBox2<string>

if (weirdoBox2.done) {
>weirdoBox2.done : boolean
>weirdoBox2 : WeirdoBox2<string>
>done : boolean

weirdoBox2.value;
>weirdoBox2.value : string | number
>weirdoBox2 : { done: true; value: string; } | { done: true; value: number; }
>value : string | number
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//// [tests/cases/compiler/discriminateWithOptionalProperty1.ts] ////

=== discriminateWithOptionalProperty1.ts ===
type Box<T> = { done?: false } | { done: true; value: T };
>Box : Symbol(Box, Decl(discriminateWithOptionalProperty1.ts, 0, 0))
>T : Symbol(T, Decl(discriminateWithOptionalProperty1.ts, 0, 9))
>done : Symbol(done, Decl(discriminateWithOptionalProperty1.ts, 0, 15))
>done : Symbol(done, Decl(discriminateWithOptionalProperty1.ts, 0, 34))
>value : Symbol(value, Decl(discriminateWithOptionalProperty1.ts, 0, 46))
>T : Symbol(T, Decl(discriminateWithOptionalProperty1.ts, 0, 9))

declare const box: Box<number>;
>box : Symbol(box, Decl(discriminateWithOptionalProperty1.ts, 2, 13))
>Box : Symbol(Box, Decl(discriminateWithOptionalProperty1.ts, 0, 0))

if (box.done) {
>box.done : Symbol(done, Decl(discriminateWithOptionalProperty1.ts, 0, 15), Decl(discriminateWithOptionalProperty1.ts, 0, 34))
>box : Symbol(box, Decl(discriminateWithOptionalProperty1.ts, 2, 13))
>done : Symbol(done, Decl(discriminateWithOptionalProperty1.ts, 0, 15), Decl(discriminateWithOptionalProperty1.ts, 0, 34))

box.value;
>box.value : Symbol(value, Decl(discriminateWithOptionalProperty1.ts, 0, 46))
>box : Symbol(box, Decl(discriminateWithOptionalProperty1.ts, 2, 13))
>value : Symbol(value, Decl(discriminateWithOptionalProperty1.ts, 0, 46))
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//// [tests/cases/compiler/discriminateWithOptionalProperty1.ts] ////

=== discriminateWithOptionalProperty1.ts ===
type Box<T> = { done?: false } | { done: true; value: T };
>Box : Box<T>
>done : false | undefined
>false : false
>done : true
>true : true
>value : T

declare const box: Box<number>;
>box : Box<number>

if (box.done) {
>box.done : boolean | undefined
>box : Box<number>
>done : boolean | undefined

box.value;
>box.value : number
>box : { done: true; value: number; }
>value : number
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//// [tests/cases/compiler/discriminateWithOptionalProperty1.ts] ////

=== discriminateWithOptionalProperty1.ts ===
type Box<T> = { done?: false } | { done: true; value: T };
>Box : Symbol(Box, Decl(discriminateWithOptionalProperty1.ts, 0, 0))
>T : Symbol(T, Decl(discriminateWithOptionalProperty1.ts, 0, 9))
>done : Symbol(done, Decl(discriminateWithOptionalProperty1.ts, 0, 15))
>done : Symbol(done, Decl(discriminateWithOptionalProperty1.ts, 0, 34))
>value : Symbol(value, Decl(discriminateWithOptionalProperty1.ts, 0, 46))
>T : Symbol(T, Decl(discriminateWithOptionalProperty1.ts, 0, 9))

declare const box: Box<number>;
>box : Symbol(box, Decl(discriminateWithOptionalProperty1.ts, 2, 13))
>Box : Symbol(Box, Decl(discriminateWithOptionalProperty1.ts, 0, 0))

if (box.done) {
>box.done : Symbol(done, Decl(discriminateWithOptionalProperty1.ts, 0, 15), Decl(discriminateWithOptionalProperty1.ts, 0, 34))
>box : Symbol(box, Decl(discriminateWithOptionalProperty1.ts, 2, 13))
>done : Symbol(done, Decl(discriminateWithOptionalProperty1.ts, 0, 15), Decl(discriminateWithOptionalProperty1.ts, 0, 34))

box.value;
>box.value : Symbol(value, Decl(discriminateWithOptionalProperty1.ts, 0, 46))
>box : Symbol(box, Decl(discriminateWithOptionalProperty1.ts, 2, 13))
>value : Symbol(value, Decl(discriminateWithOptionalProperty1.ts, 0, 46))
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//// [tests/cases/compiler/discriminateWithOptionalProperty1.ts] ////

=== discriminateWithOptionalProperty1.ts ===
type Box<T> = { done?: false } | { done: true; value: T };
>Box : Box<T>
>done : false | undefined
>false : false
>done : true
>true : true
>value : T

declare const box: Box<number>;
>box : Box<number>

if (box.done) {
>box.done : boolean | undefined
>box : Box<number>
>done : boolean | undefined

box.value;
>box.value : number
>box : { done: true; value: number; }
>value : number
}

Loading

0 comments on commit 6a011b5

Please sign in to comment.