mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-04-17 01:49:41 -05:00
Fixed a regression with discriminating unions based on a union property against undefined with strictNullChecks: false (#49648)
* Fixed a regression with discriminating unions based on a union property against `undefined` with `strictNullChecks: false` * Add additional test case from the issue comment
This commit is contained in:
committed by
GitHub
parent
7b0df1ff99
commit
a329210166
@@ -18986,7 +18986,8 @@ namespace ts {
|
||||
// Before normalization: if `source` is type an object type, and `target` is primitive,
|
||||
// skip all the checks we don't need and just return `isSimpleTypeRelatedTo` result
|
||||
if (originalSource.flags & TypeFlags.Object && originalTarget.flags & TypeFlags.Primitive) {
|
||||
if (isSimpleTypeRelatedTo(originalSource, originalTarget, relation, reportErrors ? reportError : undefined)) {
|
||||
if (relation === comparableRelation && !(originalTarget.flags & TypeFlags.Never) && isSimpleTypeRelatedTo(originalTarget, originalSource, relation) ||
|
||||
isSimpleTypeRelatedTo(originalSource, originalTarget, relation, reportErrors ? reportError : undefined)) {
|
||||
return Ternary.True;
|
||||
}
|
||||
if (reportErrors) {
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
=== tests/cases/compiler/discriminatingUnionWithUnionPropertyAgainstUndefinedWithoutStrictNullChecks.ts ===
|
||||
// strictNullChecks: false
|
||||
|
||||
// repro #49643
|
||||
|
||||
interface A {}
|
||||
>A : Symbol(A, Decl(discriminatingUnionWithUnionPropertyAgainstUndefinedWithoutStrictNullChecks.ts, 0, 0))
|
||||
|
||||
interface B {}
|
||||
>B : Symbol(B, Decl(discriminatingUnionWithUnionPropertyAgainstUndefinedWithoutStrictNullChecks.ts, 4, 14))
|
||||
|
||||
declare let opts:
|
||||
>opts : Symbol(opts, Decl(discriminatingUnionWithUnionPropertyAgainstUndefinedWithoutStrictNullChecks.ts, 7, 11))
|
||||
|
||||
| { objectRef?: undefined; getObjectRef: () => any }
|
||||
>objectRef : Symbol(objectRef, Decl(discriminatingUnionWithUnionPropertyAgainstUndefinedWithoutStrictNullChecks.ts, 8, 6))
|
||||
>getObjectRef : Symbol(getObjectRef, Decl(discriminatingUnionWithUnionPropertyAgainstUndefinedWithoutStrictNullChecks.ts, 8, 29))
|
||||
|
||||
| { objectRef: A | B; getObjectRef?: undefined };
|
||||
>objectRef : Symbol(objectRef, Decl(discriminatingUnionWithUnionPropertyAgainstUndefinedWithoutStrictNullChecks.ts, 9, 6))
|
||||
>A : Symbol(A, Decl(discriminatingUnionWithUnionPropertyAgainstUndefinedWithoutStrictNullChecks.ts, 0, 0))
|
||||
>B : Symbol(B, Decl(discriminatingUnionWithUnionPropertyAgainstUndefinedWithoutStrictNullChecks.ts, 4, 14))
|
||||
>getObjectRef : Symbol(getObjectRef, Decl(discriminatingUnionWithUnionPropertyAgainstUndefinedWithoutStrictNullChecks.ts, 9, 24))
|
||||
|
||||
opts.objectRef || opts.getObjectRef();
|
||||
>opts.objectRef : Symbol(objectRef, Decl(discriminatingUnionWithUnionPropertyAgainstUndefinedWithoutStrictNullChecks.ts, 8, 6), Decl(discriminatingUnionWithUnionPropertyAgainstUndefinedWithoutStrictNullChecks.ts, 9, 6))
|
||||
>opts : Symbol(opts, Decl(discriminatingUnionWithUnionPropertyAgainstUndefinedWithoutStrictNullChecks.ts, 7, 11))
|
||||
>objectRef : Symbol(objectRef, Decl(discriminatingUnionWithUnionPropertyAgainstUndefinedWithoutStrictNullChecks.ts, 8, 6), Decl(discriminatingUnionWithUnionPropertyAgainstUndefinedWithoutStrictNullChecks.ts, 9, 6))
|
||||
>opts.getObjectRef : Symbol(getObjectRef, Decl(discriminatingUnionWithUnionPropertyAgainstUndefinedWithoutStrictNullChecks.ts, 8, 29), Decl(discriminatingUnionWithUnionPropertyAgainstUndefinedWithoutStrictNullChecks.ts, 9, 24))
|
||||
>opts : Symbol(opts, Decl(discriminatingUnionWithUnionPropertyAgainstUndefinedWithoutStrictNullChecks.ts, 7, 11))
|
||||
>getObjectRef : Symbol(getObjectRef, Decl(discriminatingUnionWithUnionPropertyAgainstUndefinedWithoutStrictNullChecks.ts, 8, 29), Decl(discriminatingUnionWithUnionPropertyAgainstUndefinedWithoutStrictNullChecks.ts, 9, 24))
|
||||
|
||||
// repro #49643 issuecomment-1174455723
|
||||
|
||||
interface X {
|
||||
>X : Symbol(X, Decl(discriminatingUnionWithUnionPropertyAgainstUndefinedWithoutStrictNullChecks.ts, 11, 38))
|
||||
|
||||
foo: string;
|
||||
>foo : Symbol(X.foo, Decl(discriminatingUnionWithUnionPropertyAgainstUndefinedWithoutStrictNullChecks.ts, 15, 13))
|
||||
}
|
||||
|
||||
interface Y {
|
||||
>Y : Symbol(Y, Decl(discriminatingUnionWithUnionPropertyAgainstUndefinedWithoutStrictNullChecks.ts, 17, 1))
|
||||
|
||||
baz: number;
|
||||
>baz : Symbol(Y.baz, Decl(discriminatingUnionWithUnionPropertyAgainstUndefinedWithoutStrictNullChecks.ts, 19, 13))
|
||||
}
|
||||
|
||||
interface A2 {
|
||||
>A2 : Symbol(A2, Decl(discriminatingUnionWithUnionPropertyAgainstUndefinedWithoutStrictNullChecks.ts, 21, 1))
|
||||
|
||||
result: unknown;
|
||||
>result : Symbol(A2.result, Decl(discriminatingUnionWithUnionPropertyAgainstUndefinedWithoutStrictNullChecks.ts, 23, 14))
|
||||
|
||||
error: undefined;
|
||||
>error : Symbol(A2.error, Decl(discriminatingUnionWithUnionPropertyAgainstUndefinedWithoutStrictNullChecks.ts, 24, 20))
|
||||
}
|
||||
|
||||
interface B2 {
|
||||
>B2 : Symbol(B2, Decl(discriminatingUnionWithUnionPropertyAgainstUndefinedWithoutStrictNullChecks.ts, 26, 1))
|
||||
|
||||
error: X | Y;
|
||||
>error : Symbol(B2.error, Decl(discriminatingUnionWithUnionPropertyAgainstUndefinedWithoutStrictNullChecks.ts, 28, 14))
|
||||
>X : Symbol(X, Decl(discriminatingUnionWithUnionPropertyAgainstUndefinedWithoutStrictNullChecks.ts, 11, 38))
|
||||
>Y : Symbol(Y, Decl(discriminatingUnionWithUnionPropertyAgainstUndefinedWithoutStrictNullChecks.ts, 17, 1))
|
||||
}
|
||||
|
||||
const testMethod = (m: A2 | B2) => {
|
||||
>testMethod : Symbol(testMethod, Decl(discriminatingUnionWithUnionPropertyAgainstUndefinedWithoutStrictNullChecks.ts, 32, 5))
|
||||
>m : Symbol(m, Decl(discriminatingUnionWithUnionPropertyAgainstUndefinedWithoutStrictNullChecks.ts, 32, 20))
|
||||
>A2 : Symbol(A2, Decl(discriminatingUnionWithUnionPropertyAgainstUndefinedWithoutStrictNullChecks.ts, 21, 1))
|
||||
>B2 : Symbol(B2, Decl(discriminatingUnionWithUnionPropertyAgainstUndefinedWithoutStrictNullChecks.ts, 26, 1))
|
||||
|
||||
if (m.error) {
|
||||
>m.error : Symbol(error, Decl(discriminatingUnionWithUnionPropertyAgainstUndefinedWithoutStrictNullChecks.ts, 24, 20), Decl(discriminatingUnionWithUnionPropertyAgainstUndefinedWithoutStrictNullChecks.ts, 28, 14))
|
||||
>m : Symbol(m, Decl(discriminatingUnionWithUnionPropertyAgainstUndefinedWithoutStrictNullChecks.ts, 32, 20))
|
||||
>error : Symbol(error, Decl(discriminatingUnionWithUnionPropertyAgainstUndefinedWithoutStrictNullChecks.ts, 24, 20), Decl(discriminatingUnionWithUnionPropertyAgainstUndefinedWithoutStrictNullChecks.ts, 28, 14))
|
||||
|
||||
m; // should be A2 | B2
|
||||
>m : Symbol(m, Decl(discriminatingUnionWithUnionPropertyAgainstUndefinedWithoutStrictNullChecks.ts, 32, 20))
|
||||
|
||||
} else {
|
||||
m; // should be A2 | B2
|
||||
>m : Symbol(m, Decl(discriminatingUnionWithUnionPropertyAgainstUndefinedWithoutStrictNullChecks.ts, 32, 20))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
=== tests/cases/compiler/discriminatingUnionWithUnionPropertyAgainstUndefinedWithoutStrictNullChecks.ts ===
|
||||
// strictNullChecks: false
|
||||
|
||||
// repro #49643
|
||||
|
||||
interface A {}
|
||||
interface B {}
|
||||
|
||||
declare let opts:
|
||||
>opts : { objectRef?: undefined; getObjectRef: () => any; } | { objectRef: A | B; getObjectRef?: undefined; }
|
||||
|
||||
| { objectRef?: undefined; getObjectRef: () => any }
|
||||
>objectRef : undefined
|
||||
>getObjectRef : () => any
|
||||
|
||||
| { objectRef: A | B; getObjectRef?: undefined };
|
||||
>objectRef : A | B
|
||||
>getObjectRef : undefined
|
||||
|
||||
opts.objectRef || opts.getObjectRef();
|
||||
>opts.objectRef || opts.getObjectRef() : any
|
||||
>opts.objectRef : A | B
|
||||
>opts : { objectRef?: undefined; getObjectRef: () => any; } | { objectRef: A | B; getObjectRef?: undefined; }
|
||||
>objectRef : A | B
|
||||
>opts.getObjectRef() : any
|
||||
>opts.getObjectRef : () => any
|
||||
>opts : { objectRef?: undefined; getObjectRef: () => any; } | { objectRef: A | B; getObjectRef?: undefined; }
|
||||
>getObjectRef : () => any
|
||||
|
||||
// repro #49643 issuecomment-1174455723
|
||||
|
||||
interface X {
|
||||
foo: string;
|
||||
>foo : string
|
||||
}
|
||||
|
||||
interface Y {
|
||||
baz: number;
|
||||
>baz : number
|
||||
}
|
||||
|
||||
interface A2 {
|
||||
result: unknown;
|
||||
>result : unknown
|
||||
|
||||
error: undefined;
|
||||
>error : undefined
|
||||
}
|
||||
|
||||
interface B2 {
|
||||
error: X | Y;
|
||||
>error : X | Y
|
||||
}
|
||||
|
||||
const testMethod = (m: A2 | B2) => {
|
||||
>testMethod : (m: A2 | B2) => void
|
||||
>(m: A2 | B2) => { if (m.error) { m; // should be A2 | B2 } else { m; // should be A2 | B2 }} : (m: A2 | B2) => void
|
||||
>m : A2 | B2
|
||||
|
||||
if (m.error) {
|
||||
>m.error : X | Y
|
||||
>m : A2 | B2
|
||||
>error : X | Y
|
||||
|
||||
m; // should be A2 | B2
|
||||
>m : A2 | B2
|
||||
|
||||
} else {
|
||||
m; // should be A2 | B2
|
||||
>m : A2 | B2
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
// @noEmit: true
|
||||
// strictNullChecks: false
|
||||
|
||||
// repro #49643
|
||||
|
||||
interface A {}
|
||||
interface B {}
|
||||
|
||||
declare let opts:
|
||||
| { objectRef?: undefined; getObjectRef: () => any }
|
||||
| { objectRef: A | B; getObjectRef?: undefined };
|
||||
|
||||
opts.objectRef || opts.getObjectRef();
|
||||
|
||||
// repro #49643 issuecomment-1174455723
|
||||
|
||||
interface X {
|
||||
foo: string;
|
||||
}
|
||||
|
||||
interface Y {
|
||||
baz: number;
|
||||
}
|
||||
|
||||
interface A2 {
|
||||
result: unknown;
|
||||
error: undefined;
|
||||
}
|
||||
|
||||
interface B2 {
|
||||
error: X | Y;
|
||||
}
|
||||
|
||||
const testMethod = (m: A2 | B2) => {
|
||||
if (m.error) {
|
||||
m; // should be A2 | B2
|
||||
} else {
|
||||
m; // should be A2 | B2
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user