Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
DanielRosenwasser committed Aug 24, 2022
1 parent b9a5bbc commit fb717df
Show file tree
Hide file tree
Showing 5 changed files with 315 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/compiler/checker.ts
Expand Up @@ -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) &&
Expand Down
67 changes: 67 additions & 0 deletions tests/baselines/reference/weakTypesAndLiterals01.js
@@ -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;
95 changes: 95 additions & 0 deletions tests/baselines/reference/weakTypesAndLiterals01.symbols
@@ -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))
}
}

101 changes: 101 additions & 0 deletions tests/baselines/reference/weakTypesAndLiterals01.types
@@ -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;
}
}

0 comments on commit fb717df

Please sign in to comment.