Discard union types before considering weak type checks on unit-like types (#50423)

* Only check isUnitType when dealing with non-unions.

* Add test case.

* Accepted baselines.
This commit is contained in:
Daniel Rosenwasser
2022-08-24 11:39:00 -07:00
committed by GitHub
parent b9a5bbc9af
commit fb717df6bf
5 changed files with 315 additions and 1 deletions
+1 -1
View File
@@ -18901,7 +18901,7 @@ namespace ts {
}
}
const isPerformingCommonPropertyChecks = (relation !== comparableRelation || relation === comparableRelation && isLiteralType(source)) &&
const isPerformingCommonPropertyChecks = (relation !== comparableRelation || !(source.flags & TypeFlags.Union) && isLiteralType(source)) &&
!(intersectionState & IntersectionState.Target) &&
source.flags & (TypeFlags.Primitive | TypeFlags.Object | TypeFlags.Intersection) && source !== globalObjectType &&
target.flags & (TypeFlags.Object | TypeFlags.Intersection) && isWeakType(target) &&
@@ -0,0 +1,67 @@
//// [weakTypesAndLiterals01.ts]
type WeakTypes =
| { optional?: true; }
| { toLowerCase?(): string }
| { toUpperCase?(): string, otherOptionalProp?: number };
type LiteralsOrWeakTypes =
| "A"
| "B"
| WeakTypes;
declare let aOrB: "A" | "B";
const f = (arg: LiteralsOrWeakTypes) => {
if (arg === "A") {
return arg;
}
else {
return arg;
}
}
const g = (arg: WeakTypes) => {
if (arg === "A") {
return arg;
}
else {
return arg;
}
}
const h = (arg: LiteralsOrWeakTypes) => {
if (arg === aOrB) {
return arg;
}
else {
return arg;
}
}
const i = (arg: WeakTypes) => {
if (arg === aOrB) {
return arg;
}
else {
return arg;
}
}
//// [weakTypesAndLiterals01.d.ts]
type WeakTypes = {
optional?: true;
} | {
toLowerCase?(): string;
} | {
toUpperCase?(): string;
otherOptionalProp?: number;
};
type LiteralsOrWeakTypes = "A" | "B" | WeakTypes;
declare let aOrB: "A" | "B";
declare const f: (arg: LiteralsOrWeakTypes) => WeakTypes | "A" | "B";
declare const g: (arg: WeakTypes) => WeakTypes;
declare const h: (arg: LiteralsOrWeakTypes) => LiteralsOrWeakTypes;
declare const i: (arg: WeakTypes) => WeakTypes;
@@ -0,0 +1,95 @@
=== tests/cases/conformance/types/typeRelationships/comparable/weakTypesAndLiterals01.ts ===
type WeakTypes =
>WeakTypes : Symbol(WeakTypes, Decl(weakTypesAndLiterals01.ts, 0, 0))
| { optional?: true; }
>optional : Symbol(optional, Decl(weakTypesAndLiterals01.ts, 1, 7))
| { toLowerCase?(): string }
>toLowerCase : Symbol(toLowerCase, Decl(weakTypesAndLiterals01.ts, 2, 7))
| { toUpperCase?(): string, otherOptionalProp?: number };
>toUpperCase : Symbol(toUpperCase, Decl(weakTypesAndLiterals01.ts, 3, 7))
>otherOptionalProp : Symbol(otherOptionalProp, Decl(weakTypesAndLiterals01.ts, 3, 31))
type LiteralsOrWeakTypes =
>LiteralsOrWeakTypes : Symbol(LiteralsOrWeakTypes, Decl(weakTypesAndLiterals01.ts, 3, 61))
| "A"
| "B"
| WeakTypes;
>WeakTypes : Symbol(WeakTypes, Decl(weakTypesAndLiterals01.ts, 0, 0))
declare let aOrB: "A" | "B";
>aOrB : Symbol(aOrB, Decl(weakTypesAndLiterals01.ts, 10, 11))
const f = (arg: LiteralsOrWeakTypes) => {
>f : Symbol(f, Decl(weakTypesAndLiterals01.ts, 12, 5))
>arg : Symbol(arg, Decl(weakTypesAndLiterals01.ts, 12, 11))
>LiteralsOrWeakTypes : Symbol(LiteralsOrWeakTypes, Decl(weakTypesAndLiterals01.ts, 3, 61))
if (arg === "A") {
>arg : Symbol(arg, Decl(weakTypesAndLiterals01.ts, 12, 11))
return arg;
>arg : Symbol(arg, Decl(weakTypesAndLiterals01.ts, 12, 11))
}
else {
return arg;
>arg : Symbol(arg, Decl(weakTypesAndLiterals01.ts, 12, 11))
}
}
const g = (arg: WeakTypes) => {
>g : Symbol(g, Decl(weakTypesAndLiterals01.ts, 21, 5))
>arg : Symbol(arg, Decl(weakTypesAndLiterals01.ts, 21, 11))
>WeakTypes : Symbol(WeakTypes, Decl(weakTypesAndLiterals01.ts, 0, 0))
if (arg === "A") {
>arg : Symbol(arg, Decl(weakTypesAndLiterals01.ts, 21, 11))
return arg;
>arg : Symbol(arg, Decl(weakTypesAndLiterals01.ts, 21, 11))
}
else {
return arg;
>arg : Symbol(arg, Decl(weakTypesAndLiterals01.ts, 21, 11))
}
}
const h = (arg: LiteralsOrWeakTypes) => {
>h : Symbol(h, Decl(weakTypesAndLiterals01.ts, 30, 5))
>arg : Symbol(arg, Decl(weakTypesAndLiterals01.ts, 30, 11))
>LiteralsOrWeakTypes : Symbol(LiteralsOrWeakTypes, Decl(weakTypesAndLiterals01.ts, 3, 61))
if (arg === aOrB) {
>arg : Symbol(arg, Decl(weakTypesAndLiterals01.ts, 30, 11))
>aOrB : Symbol(aOrB, Decl(weakTypesAndLiterals01.ts, 10, 11))
return arg;
>arg : Symbol(arg, Decl(weakTypesAndLiterals01.ts, 30, 11))
}
else {
return arg;
>arg : Symbol(arg, Decl(weakTypesAndLiterals01.ts, 30, 11))
}
}
const i = (arg: WeakTypes) => {
>i : Symbol(i, Decl(weakTypesAndLiterals01.ts, 39, 5))
>arg : Symbol(arg, Decl(weakTypesAndLiterals01.ts, 39, 11))
>WeakTypes : Symbol(WeakTypes, Decl(weakTypesAndLiterals01.ts, 0, 0))
if (arg === aOrB) {
>arg : Symbol(arg, Decl(weakTypesAndLiterals01.ts, 39, 11))
>aOrB : Symbol(aOrB, Decl(weakTypesAndLiterals01.ts, 10, 11))
return arg;
>arg : Symbol(arg, Decl(weakTypesAndLiterals01.ts, 39, 11))
}
else {
return arg;
>arg : Symbol(arg, Decl(weakTypesAndLiterals01.ts, 39, 11))
}
}
@@ -0,0 +1,101 @@
=== tests/cases/conformance/types/typeRelationships/comparable/weakTypesAndLiterals01.ts ===
type WeakTypes =
>WeakTypes : { optional?: true | undefined; } | { toLowerCase?(): string; } | { toUpperCase?(): string; otherOptionalProp?: number | undefined; }
| { optional?: true; }
>optional : true | undefined
>true : true
| { toLowerCase?(): string }
>toLowerCase : (() => string) | undefined
| { toUpperCase?(): string, otherOptionalProp?: number };
>toUpperCase : (() => string) | undefined
>otherOptionalProp : number | undefined
type LiteralsOrWeakTypes =
>LiteralsOrWeakTypes : WeakTypes | "A" | "B"
| "A"
| "B"
| WeakTypes;
declare let aOrB: "A" | "B";
>aOrB : "A" | "B"
const f = (arg: LiteralsOrWeakTypes) => {
>f : (arg: LiteralsOrWeakTypes) => WeakTypes | "A" | "B"
>(arg: LiteralsOrWeakTypes) => { if (arg === "A") { return arg; } else { return arg; }} : (arg: LiteralsOrWeakTypes) => WeakTypes | "A" | "B"
>arg : LiteralsOrWeakTypes
if (arg === "A") {
>arg === "A" : boolean
>arg : LiteralsOrWeakTypes
>"A" : "A"
return arg;
>arg : { toLowerCase?(): string; } | { toUpperCase?(): string; otherOptionalProp?: number | undefined; } | "A"
}
else {
return arg;
>arg : WeakTypes | "B"
}
}
const g = (arg: WeakTypes) => {
>g : (arg: WeakTypes) => WeakTypes
>(arg: WeakTypes) => { if (arg === "A") { return arg; } else { return arg; }} : (arg: WeakTypes) => WeakTypes
>arg : WeakTypes
if (arg === "A") {
>arg === "A" : boolean
>arg : WeakTypes
>"A" : "A"
return arg;
>arg : { toLowerCase?(): string; } | { toUpperCase?(): string; otherOptionalProp?: number | undefined; }
}
else {
return arg;
>arg : WeakTypes
}
}
const h = (arg: LiteralsOrWeakTypes) => {
>h : (arg: LiteralsOrWeakTypes) => LiteralsOrWeakTypes
>(arg: LiteralsOrWeakTypes) => { if (arg === aOrB) { return arg; } else { return arg; }} : (arg: LiteralsOrWeakTypes) => LiteralsOrWeakTypes
>arg : LiteralsOrWeakTypes
if (arg === aOrB) {
>arg === aOrB : boolean
>arg : LiteralsOrWeakTypes
>aOrB : "A" | "B"
return arg;
>arg : { toLowerCase?(): string; } | { toUpperCase?(): string; otherOptionalProp?: number | undefined; } | "A" | "B"
}
else {
return arg;
>arg : LiteralsOrWeakTypes
}
}
const i = (arg: WeakTypes) => {
>i : (arg: WeakTypes) => WeakTypes
>(arg: WeakTypes) => { if (arg === aOrB) { return arg; } else { return arg; }} : (arg: WeakTypes) => WeakTypes
>arg : WeakTypes
if (arg === aOrB) {
>arg === aOrB : boolean
>arg : WeakTypes
>aOrB : "A" | "B"
return arg;
>arg : { toLowerCase?(): string; } | { toUpperCase?(): string; otherOptionalProp?: number | undefined; }
}
else {
return arg;
>arg : WeakTypes
}
}
@@ -0,0 +1,51 @@
// @strict: true
// @declaration: true
// @emitDeclarationOnly: true
type WeakTypes =
| { optional?: true; }
| { toLowerCase?(): string }
| { toUpperCase?(): string, otherOptionalProp?: number };
type LiteralsOrWeakTypes =
| "A"
| "B"
| WeakTypes;
declare let aOrB: "A" | "B";
const f = (arg: LiteralsOrWeakTypes) => {
if (arg === "A") {
return arg;
}
else {
return arg;
}
}
const g = (arg: WeakTypes) => {
if (arg === "A") {
return arg;
}
else {
return arg;
}
}
const h = (arg: LiteralsOrWeakTypes) => {
if (arg === aOrB) {
return arg;
}
else {
return arg;
}
}
const i = (arg: WeakTypes) => {
if (arg === aOrB) {
return arg;
}
else {
return arg;
}
}