diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 1ac041a3653c2..259ffc6312017 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -25096,7 +25096,7 @@ namespace ts { const narrowedPropType = narrowType(propType); return filterType(type, t => { const discriminantType = getTypeOfPropertyOrIndexSignature(t, propName); - return !(narrowedPropType.flags & TypeFlags.Never) && isTypeComparableTo(narrowedPropType, discriminantType); + return !(narrowedPropType.flags & TypeFlags.Never) && areTypesComparable(narrowedPropType, discriminantType); }); } diff --git a/tests/baselines/reference/undefinedAsDiscriminantWithUnknown(strictnullchecks=false).js b/tests/baselines/reference/undefinedAsDiscriminantWithUnknown(strictnullchecks=false).js new file mode 100644 index 0000000000000..c30c4d6723deb --- /dev/null +++ b/tests/baselines/reference/undefinedAsDiscriminantWithUnknown(strictnullchecks=false).js @@ -0,0 +1,23 @@ +//// [undefinedAsDiscriminantWithUnknown.ts] +type S = +| { type: 'string', value: string } +| { type: 'number', value: number } +| { type: 'unknown', value: unknown } +| { value: undefined }; + +declare var s: S + +if (s.value !== undefined) { + s; +} +else { + s; +} + +//// [undefinedAsDiscriminantWithUnknown.js] +if (s.value !== undefined) { + s; +} +else { + s; +} diff --git a/tests/baselines/reference/undefinedAsDiscriminantWithUnknown(strictnullchecks=false).symbols b/tests/baselines/reference/undefinedAsDiscriminantWithUnknown(strictnullchecks=false).symbols new file mode 100644 index 0000000000000..13da7db0555c1 --- /dev/null +++ b/tests/baselines/reference/undefinedAsDiscriminantWithUnknown(strictnullchecks=false).symbols @@ -0,0 +1,36 @@ +=== tests/cases/compiler/undefinedAsDiscriminantWithUnknown.ts === +type S = +>S : Symbol(S, Decl(undefinedAsDiscriminantWithUnknown.ts, 0, 0)) + +| { type: 'string', value: string } +>type : Symbol(type, Decl(undefinedAsDiscriminantWithUnknown.ts, 1, 3)) +>value : Symbol(value, Decl(undefinedAsDiscriminantWithUnknown.ts, 1, 19)) + +| { type: 'number', value: number } +>type : Symbol(type, Decl(undefinedAsDiscriminantWithUnknown.ts, 2, 3)) +>value : Symbol(value, Decl(undefinedAsDiscriminantWithUnknown.ts, 2, 19)) + +| { type: 'unknown', value: unknown } +>type : Symbol(type, Decl(undefinedAsDiscriminantWithUnknown.ts, 3, 3)) +>value : Symbol(value, Decl(undefinedAsDiscriminantWithUnknown.ts, 3, 20)) + +| { value: undefined }; +>value : Symbol(value, Decl(undefinedAsDiscriminantWithUnknown.ts, 4, 3)) + +declare var s: S +>s : Symbol(s, Decl(undefinedAsDiscriminantWithUnknown.ts, 6, 11)) +>S : Symbol(S, Decl(undefinedAsDiscriminantWithUnknown.ts, 0, 0)) + +if (s.value !== undefined) { +>s.value : Symbol(value, Decl(undefinedAsDiscriminantWithUnknown.ts, 1, 19), Decl(undefinedAsDiscriminantWithUnknown.ts, 2, 19), Decl(undefinedAsDiscriminantWithUnknown.ts, 3, 20), Decl(undefinedAsDiscriminantWithUnknown.ts, 4, 3)) +>s : Symbol(s, Decl(undefinedAsDiscriminantWithUnknown.ts, 6, 11)) +>value : Symbol(value, Decl(undefinedAsDiscriminantWithUnknown.ts, 1, 19), Decl(undefinedAsDiscriminantWithUnknown.ts, 2, 19), Decl(undefinedAsDiscriminantWithUnknown.ts, 3, 20), Decl(undefinedAsDiscriminantWithUnknown.ts, 4, 3)) +>undefined : Symbol(undefined) + + s; +>s : Symbol(s, Decl(undefinedAsDiscriminantWithUnknown.ts, 6, 11)) +} +else { + s; +>s : Symbol(s, Decl(undefinedAsDiscriminantWithUnknown.ts, 6, 11)) +} diff --git a/tests/baselines/reference/undefinedAsDiscriminantWithUnknown(strictnullchecks=false).types b/tests/baselines/reference/undefinedAsDiscriminantWithUnknown(strictnullchecks=false).types new file mode 100644 index 0000000000000..af09de9d3d839 --- /dev/null +++ b/tests/baselines/reference/undefinedAsDiscriminantWithUnknown(strictnullchecks=false).types @@ -0,0 +1,36 @@ +=== tests/cases/compiler/undefinedAsDiscriminantWithUnknown.ts === +type S = +>S : { type: 'string'; value: string; } | { type: 'number'; value: number; } | { type: 'unknown'; value: unknown; } | { value: undefined; } + +| { type: 'string', value: string } +>type : "string" +>value : string + +| { type: 'number', value: number } +>type : "number" +>value : number + +| { type: 'unknown', value: unknown } +>type : "unknown" +>value : unknown + +| { value: undefined }; +>value : undefined + +declare var s: S +>s : S + +if (s.value !== undefined) { +>s.value !== undefined : boolean +>s.value : unknown +>s : S +>value : unknown +>undefined : undefined + + s; +>s : S +} +else { + s; +>s : S +} diff --git a/tests/baselines/reference/undefinedAsDiscriminantWithUnknown(strictnullchecks=true).js b/tests/baselines/reference/undefinedAsDiscriminantWithUnknown(strictnullchecks=true).js new file mode 100644 index 0000000000000..c30c4d6723deb --- /dev/null +++ b/tests/baselines/reference/undefinedAsDiscriminantWithUnknown(strictnullchecks=true).js @@ -0,0 +1,23 @@ +//// [undefinedAsDiscriminantWithUnknown.ts] +type S = +| { type: 'string', value: string } +| { type: 'number', value: number } +| { type: 'unknown', value: unknown } +| { value: undefined }; + +declare var s: S + +if (s.value !== undefined) { + s; +} +else { + s; +} + +//// [undefinedAsDiscriminantWithUnknown.js] +if (s.value !== undefined) { + s; +} +else { + s; +} diff --git a/tests/baselines/reference/undefinedAsDiscriminantWithUnknown(strictnullchecks=true).symbols b/tests/baselines/reference/undefinedAsDiscriminantWithUnknown(strictnullchecks=true).symbols new file mode 100644 index 0000000000000..13da7db0555c1 --- /dev/null +++ b/tests/baselines/reference/undefinedAsDiscriminantWithUnknown(strictnullchecks=true).symbols @@ -0,0 +1,36 @@ +=== tests/cases/compiler/undefinedAsDiscriminantWithUnknown.ts === +type S = +>S : Symbol(S, Decl(undefinedAsDiscriminantWithUnknown.ts, 0, 0)) + +| { type: 'string', value: string } +>type : Symbol(type, Decl(undefinedAsDiscriminantWithUnknown.ts, 1, 3)) +>value : Symbol(value, Decl(undefinedAsDiscriminantWithUnknown.ts, 1, 19)) + +| { type: 'number', value: number } +>type : Symbol(type, Decl(undefinedAsDiscriminantWithUnknown.ts, 2, 3)) +>value : Symbol(value, Decl(undefinedAsDiscriminantWithUnknown.ts, 2, 19)) + +| { type: 'unknown', value: unknown } +>type : Symbol(type, Decl(undefinedAsDiscriminantWithUnknown.ts, 3, 3)) +>value : Symbol(value, Decl(undefinedAsDiscriminantWithUnknown.ts, 3, 20)) + +| { value: undefined }; +>value : Symbol(value, Decl(undefinedAsDiscriminantWithUnknown.ts, 4, 3)) + +declare var s: S +>s : Symbol(s, Decl(undefinedAsDiscriminantWithUnknown.ts, 6, 11)) +>S : Symbol(S, Decl(undefinedAsDiscriminantWithUnknown.ts, 0, 0)) + +if (s.value !== undefined) { +>s.value : Symbol(value, Decl(undefinedAsDiscriminantWithUnknown.ts, 1, 19), Decl(undefinedAsDiscriminantWithUnknown.ts, 2, 19), Decl(undefinedAsDiscriminantWithUnknown.ts, 3, 20), Decl(undefinedAsDiscriminantWithUnknown.ts, 4, 3)) +>s : Symbol(s, Decl(undefinedAsDiscriminantWithUnknown.ts, 6, 11)) +>value : Symbol(value, Decl(undefinedAsDiscriminantWithUnknown.ts, 1, 19), Decl(undefinedAsDiscriminantWithUnknown.ts, 2, 19), Decl(undefinedAsDiscriminantWithUnknown.ts, 3, 20), Decl(undefinedAsDiscriminantWithUnknown.ts, 4, 3)) +>undefined : Symbol(undefined) + + s; +>s : Symbol(s, Decl(undefinedAsDiscriminantWithUnknown.ts, 6, 11)) +} +else { + s; +>s : Symbol(s, Decl(undefinedAsDiscriminantWithUnknown.ts, 6, 11)) +} diff --git a/tests/baselines/reference/undefinedAsDiscriminantWithUnknown(strictnullchecks=true).types b/tests/baselines/reference/undefinedAsDiscriminantWithUnknown(strictnullchecks=true).types new file mode 100644 index 0000000000000..69d640efe7337 --- /dev/null +++ b/tests/baselines/reference/undefinedAsDiscriminantWithUnknown(strictnullchecks=true).types @@ -0,0 +1,36 @@ +=== tests/cases/compiler/undefinedAsDiscriminantWithUnknown.ts === +type S = +>S : { type: 'string'; value: string; } | { type: 'number'; value: number; } | { type: 'unknown'; value: unknown; } | { value: undefined; } + +| { type: 'string', value: string } +>type : "string" +>value : string + +| { type: 'number', value: number } +>type : "number" +>value : number + +| { type: 'unknown', value: unknown } +>type : "unknown" +>value : unknown + +| { value: undefined }; +>value : undefined + +declare var s: S +>s : S + +if (s.value !== undefined) { +>s.value !== undefined : boolean +>s.value : unknown +>s : S +>value : unknown +>undefined : undefined + + s; +>s : { type: "string"; value: string; } | { type: "number"; value: number; } | { type: "unknown"; value: unknown; } +} +else { + s; +>s : { type: "unknown"; value: unknown; } | { value: undefined; } +} diff --git a/tests/cases/compiler/undefinedAsDiscriminantWithUnknown.ts b/tests/cases/compiler/undefinedAsDiscriminantWithUnknown.ts new file mode 100644 index 0000000000000..6a6cf1007b0bb --- /dev/null +++ b/tests/cases/compiler/undefinedAsDiscriminantWithUnknown.ts @@ -0,0 +1,16 @@ +// @strictNullChecks: true,false + +type S = +| { type: 'string', value: string } +| { type: 'number', value: number } +| { type: 'unknown', value: unknown } +| { value: undefined }; + +declare var s: S + +if (s.value !== undefined) { + s; +} +else { + s; +} \ No newline at end of file