diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 7b6d49cf8f9c4..e3e6b947bde73 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -18821,7 +18821,8 @@ m2: ${(this.mapper2 as unknown as DebugTypeMapper).__debugToString().split("\n") } } - const isPerformingCommonPropertyChecks = relation !== comparableRelation && !(intersectionState & IntersectionState.Target) && + const isPerformingCommonPropertyChecks = (relation !== comparableRelation || relation === comparableRelation && isLiteralType(source)) && + !(intersectionState & IntersectionState.Target) && source.flags & (TypeFlags.Primitive | TypeFlags.Object | TypeFlags.Intersection) && source !== globalObjectType && target.flags & (TypeFlags.Object | TypeFlags.Intersection) && isWeakType(target) && (getPropertiesOfType(source).length > 0 || typeHasCallOrConstructSignatures(source)); diff --git a/tests/baselines/reference/weakTypeAndPrimitiveNarrowing.js b/tests/baselines/reference/weakTypeAndPrimitiveNarrowing.js new file mode 100644 index 0000000000000..d9736d75f2d4e --- /dev/null +++ b/tests/baselines/reference/weakTypeAndPrimitiveNarrowing.js @@ -0,0 +1,50 @@ +//// [weakTypeAndPrimitiveNarrowing.ts] +type LiteralsAndWeakTypes = + | 'A' + | 'B' + | { optional?: true } + | { toLowerCase?(): string } + | { toUpperCase?(): string, otherOptionalProp?: number }; + +const g = (arg: LiteralsAndWeakTypes) => { + if (arg === 'A') { + arg; + } else { + arg; + } +} + +type PrimitivesAndWeakTypes = + | string + | number + | { optional?: true } + | { toLowerCase?(): string } + | { toUpperCase?(): string, otherOptionalProp?: number }; + +const h = (arg: PrimitivesAndWeakTypes) => { + if (arg === 'A') { + arg; + } else { + arg; + } +} + + +//// [weakTypeAndPrimitiveNarrowing.js] +"use strict"; +var g = function (arg) { + if (arg === 'A') { + arg; + } + else { + arg; + } +}; +var h = function (arg) { + if (arg === 'A') { + arg; + } + else { + arg; + } +}; diff --git a/tests/baselines/reference/weakTypeAndPrimitiveNarrowing.symbols b/tests/baselines/reference/weakTypeAndPrimitiveNarrowing.symbols new file mode 100644 index 0000000000000..0d1f0edab74cf --- /dev/null +++ b/tests/baselines/reference/weakTypeAndPrimitiveNarrowing.symbols @@ -0,0 +1,65 @@ +=== tests/cases/compiler/weakTypeAndPrimitiveNarrowing.ts === +type LiteralsAndWeakTypes = +>LiteralsAndWeakTypes : Symbol(LiteralsAndWeakTypes, Decl(weakTypeAndPrimitiveNarrowing.ts, 0, 0)) + + | 'A' + | 'B' + | { optional?: true } +>optional : Symbol(optional, Decl(weakTypeAndPrimitiveNarrowing.ts, 3, 5)) + + | { toLowerCase?(): string } +>toLowerCase : Symbol(toLowerCase, Decl(weakTypeAndPrimitiveNarrowing.ts, 4, 5)) + + | { toUpperCase?(): string, otherOptionalProp?: number }; +>toUpperCase : Symbol(toUpperCase, Decl(weakTypeAndPrimitiveNarrowing.ts, 5, 5)) +>otherOptionalProp : Symbol(otherOptionalProp, Decl(weakTypeAndPrimitiveNarrowing.ts, 5, 29)) + +const g = (arg: LiteralsAndWeakTypes) => { +>g : Symbol(g, Decl(weakTypeAndPrimitiveNarrowing.ts, 7, 5)) +>arg : Symbol(arg, Decl(weakTypeAndPrimitiveNarrowing.ts, 7, 11)) +>LiteralsAndWeakTypes : Symbol(LiteralsAndWeakTypes, Decl(weakTypeAndPrimitiveNarrowing.ts, 0, 0)) + + if (arg === 'A') { +>arg : Symbol(arg, Decl(weakTypeAndPrimitiveNarrowing.ts, 7, 11)) + + arg; +>arg : Symbol(arg, Decl(weakTypeAndPrimitiveNarrowing.ts, 7, 11)) + + } else { + arg; +>arg : Symbol(arg, Decl(weakTypeAndPrimitiveNarrowing.ts, 7, 11)) + } +} + +type PrimitivesAndWeakTypes = +>PrimitivesAndWeakTypes : Symbol(PrimitivesAndWeakTypes, Decl(weakTypeAndPrimitiveNarrowing.ts, 13, 1)) + + | string + | number + | { optional?: true } +>optional : Symbol(optional, Decl(weakTypeAndPrimitiveNarrowing.ts, 18, 5)) + + | { toLowerCase?(): string } +>toLowerCase : Symbol(toLowerCase, Decl(weakTypeAndPrimitiveNarrowing.ts, 19, 5)) + + | { toUpperCase?(): string, otherOptionalProp?: number }; +>toUpperCase : Symbol(toUpperCase, Decl(weakTypeAndPrimitiveNarrowing.ts, 20, 5)) +>otherOptionalProp : Symbol(otherOptionalProp, Decl(weakTypeAndPrimitiveNarrowing.ts, 20, 29)) + +const h = (arg: PrimitivesAndWeakTypes) => { +>h : Symbol(h, Decl(weakTypeAndPrimitiveNarrowing.ts, 22, 5)) +>arg : Symbol(arg, Decl(weakTypeAndPrimitiveNarrowing.ts, 22, 11)) +>PrimitivesAndWeakTypes : Symbol(PrimitivesAndWeakTypes, Decl(weakTypeAndPrimitiveNarrowing.ts, 13, 1)) + + if (arg === 'A') { +>arg : Symbol(arg, Decl(weakTypeAndPrimitiveNarrowing.ts, 22, 11)) + + arg; +>arg : Symbol(arg, Decl(weakTypeAndPrimitiveNarrowing.ts, 22, 11)) + + } else { + arg; +>arg : Symbol(arg, Decl(weakTypeAndPrimitiveNarrowing.ts, 22, 11)) + } +} + diff --git a/tests/baselines/reference/weakTypeAndPrimitiveNarrowing.types b/tests/baselines/reference/weakTypeAndPrimitiveNarrowing.types new file mode 100644 index 0000000000000..e0db0a93b8d0a --- /dev/null +++ b/tests/baselines/reference/weakTypeAndPrimitiveNarrowing.types @@ -0,0 +1,71 @@ +=== tests/cases/compiler/weakTypeAndPrimitiveNarrowing.ts === +type LiteralsAndWeakTypes = +>LiteralsAndWeakTypes : { optional?: true | undefined; } | { toLowerCase?(): string; } | { toUpperCase?(): string; otherOptionalProp?: number | undefined; } | "A" | "B" + + | 'A' + | 'B' + | { optional?: true } +>optional : true | undefined +>true : true + + | { toLowerCase?(): string } +>toLowerCase : (() => string) | undefined + + | { toUpperCase?(): string, otherOptionalProp?: number }; +>toUpperCase : (() => string) | undefined +>otherOptionalProp : number | undefined + +const g = (arg: LiteralsAndWeakTypes) => { +>g : (arg: LiteralsAndWeakTypes) => void +>(arg: LiteralsAndWeakTypes) => { if (arg === 'A') { arg; } else { arg; }} : (arg: LiteralsAndWeakTypes) => void +>arg : LiteralsAndWeakTypes + + if (arg === 'A') { +>arg === 'A' : boolean +>arg : LiteralsAndWeakTypes +>'A' : "A" + + arg; +>arg : { toLowerCase?(): string; } | { toUpperCase?(): string; otherOptionalProp?: number | undefined; } | "A" + + } else { + arg; +>arg : { optional?: true | undefined; } | { toLowerCase?(): string; } | { toUpperCase?(): string; otherOptionalProp?: number | undefined; } | "B" + } +} + +type PrimitivesAndWeakTypes = +>PrimitivesAndWeakTypes : string | number | { optional?: true | undefined; } | { toLowerCase?(): string; } | { toUpperCase?(): string; otherOptionalProp?: number | undefined; } + + | string + | number + | { optional?: true } +>optional : true | undefined +>true : true + + | { toLowerCase?(): string } +>toLowerCase : (() => string) | undefined + + | { toUpperCase?(): string, otherOptionalProp?: number }; +>toUpperCase : (() => string) | undefined +>otherOptionalProp : number | undefined + +const h = (arg: PrimitivesAndWeakTypes) => { +>h : (arg: PrimitivesAndWeakTypes) => void +>(arg: PrimitivesAndWeakTypes) => { if (arg === 'A') { arg; } else { arg; }} : (arg: PrimitivesAndWeakTypes) => void +>arg : PrimitivesAndWeakTypes + + if (arg === 'A') { +>arg === 'A' : boolean +>arg : PrimitivesAndWeakTypes +>'A' : "A" + + arg; +>arg : "A" | { toLowerCase?(): string; } | { toUpperCase?(): string; otherOptionalProp?: number | undefined; } + + } else { + arg; +>arg : PrimitivesAndWeakTypes + } +} + diff --git a/tests/cases/compiler/weakTypeAndPrimitiveNarrowing.ts b/tests/cases/compiler/weakTypeAndPrimitiveNarrowing.ts new file mode 100644 index 0000000000000..df3d9de530b39 --- /dev/null +++ b/tests/cases/compiler/weakTypeAndPrimitiveNarrowing.ts @@ -0,0 +1,31 @@ +// @strict: true + +type LiteralsAndWeakTypes = + | 'A' + | 'B' + | { optional?: true } + | { toLowerCase?(): string } + | { toUpperCase?(): string, otherOptionalProp?: number }; + +const g = (arg: LiteralsAndWeakTypes) => { + if (arg === 'A') { + arg; + } else { + arg; + } +} + +type PrimitivesAndWeakTypes = + | string + | number + | { optional?: true } + | { toLowerCase?(): string } + | { toUpperCase?(): string, otherOptionalProp?: number }; + +const h = (arg: PrimitivesAndWeakTypes) => { + if (arg === 'A') { + arg; + } else { + arg; + } +}