mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-05 08:11:30 -06:00
Allow {} to narrow in same special cases as unknown (#50601)
This commit is contained in:
parent
854d448e5c
commit
856c7c5fdd
@ -25288,14 +25288,19 @@ namespace ts {
|
||||
assumeTrue = !assumeTrue;
|
||||
}
|
||||
const valueType = getTypeOfExpression(value);
|
||||
if ((type.flags & TypeFlags.Unknown) && assumeTrue && (operator === SyntaxKind.EqualsEqualsEqualsToken || operator === SyntaxKind.ExclamationEqualsEqualsToken)) {
|
||||
if (((type.flags & TypeFlags.Unknown) || isEmptyAnonymousObjectType(type) && !(valueType.flags & TypeFlags.Nullable)) &&
|
||||
assumeTrue &&
|
||||
(operator === SyntaxKind.EqualsEqualsEqualsToken || operator === SyntaxKind.ExclamationEqualsEqualsToken)
|
||||
) {
|
||||
if (valueType.flags & (TypeFlags.Primitive | TypeFlags.NonPrimitive)) {
|
||||
return valueType;
|
||||
}
|
||||
if (valueType.flags & TypeFlags.Object) {
|
||||
return nonPrimitiveType;
|
||||
}
|
||||
return type;
|
||||
if (type.flags & TypeFlags.Unknown) {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
if (valueType.flags & TypeFlags.Nullable) {
|
||||
if (!strictNullChecks) {
|
||||
|
||||
@ -0,0 +1,139 @@
|
||||
//// [emptyAnonymousObjectNarrowing.ts]
|
||||
declare let nonNull: {};
|
||||
if (nonNull === "foo") {
|
||||
nonNull;
|
||||
}
|
||||
else {
|
||||
nonNull;
|
||||
}
|
||||
|
||||
declare let obj: { a: string };
|
||||
if (nonNull === obj) {
|
||||
nonNull;
|
||||
}
|
||||
else {
|
||||
nonNull;
|
||||
}
|
||||
|
||||
function f1<T>(x: T) {
|
||||
if (nonNull === x) {
|
||||
nonNull;
|
||||
}
|
||||
else {
|
||||
nonNull;
|
||||
}
|
||||
}
|
||||
|
||||
function f2<T extends object>(x: T) {
|
||||
if (nonNull === x) {
|
||||
nonNull;
|
||||
}
|
||||
else {
|
||||
nonNull;
|
||||
}
|
||||
}
|
||||
|
||||
declare let union: "xyz" | { a: string } | undefined;
|
||||
if (nonNull === union) {
|
||||
nonNull;
|
||||
}
|
||||
else {
|
||||
nonNull;
|
||||
}
|
||||
|
||||
if (nonNull === undefined) {
|
||||
nonNull;
|
||||
}
|
||||
else {
|
||||
nonNull;
|
||||
}
|
||||
|
||||
if (nonNull === null) {
|
||||
nonNull;
|
||||
}
|
||||
else {
|
||||
nonNull;
|
||||
}
|
||||
|
||||
if (nonNull == undefined) {
|
||||
nonNull;
|
||||
}
|
||||
else {
|
||||
nonNull;
|
||||
}
|
||||
|
||||
// Repro from #50567
|
||||
const foo = (value: unknown): string => {
|
||||
if (!value) {
|
||||
return 'foo';
|
||||
}
|
||||
if (value === 'xyz') {
|
||||
return value; // Type '{}' is not assignable to type 'string'.
|
||||
}
|
||||
return '';
|
||||
};
|
||||
|
||||
|
||||
//// [emptyAnonymousObjectNarrowing.js]
|
||||
if (nonNull === "foo") {
|
||||
nonNull;
|
||||
}
|
||||
else {
|
||||
nonNull;
|
||||
}
|
||||
if (nonNull === obj) {
|
||||
nonNull;
|
||||
}
|
||||
else {
|
||||
nonNull;
|
||||
}
|
||||
function f1(x) {
|
||||
if (nonNull === x) {
|
||||
nonNull;
|
||||
}
|
||||
else {
|
||||
nonNull;
|
||||
}
|
||||
}
|
||||
function f2(x) {
|
||||
if (nonNull === x) {
|
||||
nonNull;
|
||||
}
|
||||
else {
|
||||
nonNull;
|
||||
}
|
||||
}
|
||||
if (nonNull === union) {
|
||||
nonNull;
|
||||
}
|
||||
else {
|
||||
nonNull;
|
||||
}
|
||||
if (nonNull === undefined) {
|
||||
nonNull;
|
||||
}
|
||||
else {
|
||||
nonNull;
|
||||
}
|
||||
if (nonNull === null) {
|
||||
nonNull;
|
||||
}
|
||||
else {
|
||||
nonNull;
|
||||
}
|
||||
if (nonNull == undefined) {
|
||||
nonNull;
|
||||
}
|
||||
else {
|
||||
nonNull;
|
||||
}
|
||||
// Repro from #50567
|
||||
var foo = function (value) {
|
||||
if (!value) {
|
||||
return 'foo';
|
||||
}
|
||||
if (value === 'xyz') {
|
||||
return value; // Type '{}' is not assignable to type 'string'.
|
||||
}
|
||||
return '';
|
||||
};
|
||||
@ -0,0 +1,139 @@
|
||||
=== tests/cases/compiler/emptyAnonymousObjectNarrowing.ts ===
|
||||
declare let nonNull: {};
|
||||
>nonNull : Symbol(nonNull, Decl(emptyAnonymousObjectNarrowing.ts, 0, 11))
|
||||
|
||||
if (nonNull === "foo") {
|
||||
>nonNull : Symbol(nonNull, Decl(emptyAnonymousObjectNarrowing.ts, 0, 11))
|
||||
|
||||
nonNull;
|
||||
>nonNull : Symbol(nonNull, Decl(emptyAnonymousObjectNarrowing.ts, 0, 11))
|
||||
}
|
||||
else {
|
||||
nonNull;
|
||||
>nonNull : Symbol(nonNull, Decl(emptyAnonymousObjectNarrowing.ts, 0, 11))
|
||||
}
|
||||
|
||||
declare let obj: { a: string };
|
||||
>obj : Symbol(obj, Decl(emptyAnonymousObjectNarrowing.ts, 8, 11))
|
||||
>a : Symbol(a, Decl(emptyAnonymousObjectNarrowing.ts, 8, 18))
|
||||
|
||||
if (nonNull === obj) {
|
||||
>nonNull : Symbol(nonNull, Decl(emptyAnonymousObjectNarrowing.ts, 0, 11))
|
||||
>obj : Symbol(obj, Decl(emptyAnonymousObjectNarrowing.ts, 8, 11))
|
||||
|
||||
nonNull;
|
||||
>nonNull : Symbol(nonNull, Decl(emptyAnonymousObjectNarrowing.ts, 0, 11))
|
||||
}
|
||||
else {
|
||||
nonNull;
|
||||
>nonNull : Symbol(nonNull, Decl(emptyAnonymousObjectNarrowing.ts, 0, 11))
|
||||
}
|
||||
|
||||
function f1<T>(x: T) {
|
||||
>f1 : Symbol(f1, Decl(emptyAnonymousObjectNarrowing.ts, 14, 1))
|
||||
>T : Symbol(T, Decl(emptyAnonymousObjectNarrowing.ts, 16, 12))
|
||||
>x : Symbol(x, Decl(emptyAnonymousObjectNarrowing.ts, 16, 15))
|
||||
>T : Symbol(T, Decl(emptyAnonymousObjectNarrowing.ts, 16, 12))
|
||||
|
||||
if (nonNull === x) {
|
||||
>nonNull : Symbol(nonNull, Decl(emptyAnonymousObjectNarrowing.ts, 0, 11))
|
||||
>x : Symbol(x, Decl(emptyAnonymousObjectNarrowing.ts, 16, 15))
|
||||
|
||||
nonNull;
|
||||
>nonNull : Symbol(nonNull, Decl(emptyAnonymousObjectNarrowing.ts, 0, 11))
|
||||
}
|
||||
else {
|
||||
nonNull;
|
||||
>nonNull : Symbol(nonNull, Decl(emptyAnonymousObjectNarrowing.ts, 0, 11))
|
||||
}
|
||||
}
|
||||
|
||||
function f2<T extends object>(x: T) {
|
||||
>f2 : Symbol(f2, Decl(emptyAnonymousObjectNarrowing.ts, 23, 1))
|
||||
>T : Symbol(T, Decl(emptyAnonymousObjectNarrowing.ts, 25, 12))
|
||||
>x : Symbol(x, Decl(emptyAnonymousObjectNarrowing.ts, 25, 30))
|
||||
>T : Symbol(T, Decl(emptyAnonymousObjectNarrowing.ts, 25, 12))
|
||||
|
||||
if (nonNull === x) {
|
||||
>nonNull : Symbol(nonNull, Decl(emptyAnonymousObjectNarrowing.ts, 0, 11))
|
||||
>x : Symbol(x, Decl(emptyAnonymousObjectNarrowing.ts, 25, 30))
|
||||
|
||||
nonNull;
|
||||
>nonNull : Symbol(nonNull, Decl(emptyAnonymousObjectNarrowing.ts, 0, 11))
|
||||
}
|
||||
else {
|
||||
nonNull;
|
||||
>nonNull : Symbol(nonNull, Decl(emptyAnonymousObjectNarrowing.ts, 0, 11))
|
||||
}
|
||||
}
|
||||
|
||||
declare let union: "xyz" | { a: string } | undefined;
|
||||
>union : Symbol(union, Decl(emptyAnonymousObjectNarrowing.ts, 34, 11))
|
||||
>a : Symbol(a, Decl(emptyAnonymousObjectNarrowing.ts, 34, 28))
|
||||
|
||||
if (nonNull === union) {
|
||||
>nonNull : Symbol(nonNull, Decl(emptyAnonymousObjectNarrowing.ts, 0, 11))
|
||||
>union : Symbol(union, Decl(emptyAnonymousObjectNarrowing.ts, 34, 11))
|
||||
|
||||
nonNull;
|
||||
>nonNull : Symbol(nonNull, Decl(emptyAnonymousObjectNarrowing.ts, 0, 11))
|
||||
}
|
||||
else {
|
||||
nonNull;
|
||||
>nonNull : Symbol(nonNull, Decl(emptyAnonymousObjectNarrowing.ts, 0, 11))
|
||||
}
|
||||
|
||||
if (nonNull === undefined) {
|
||||
>nonNull : Symbol(nonNull, Decl(emptyAnonymousObjectNarrowing.ts, 0, 11))
|
||||
>undefined : Symbol(undefined)
|
||||
|
||||
nonNull;
|
||||
>nonNull : Symbol(nonNull, Decl(emptyAnonymousObjectNarrowing.ts, 0, 11))
|
||||
}
|
||||
else {
|
||||
nonNull;
|
||||
>nonNull : Symbol(nonNull, Decl(emptyAnonymousObjectNarrowing.ts, 0, 11))
|
||||
}
|
||||
|
||||
if (nonNull === null) {
|
||||
>nonNull : Symbol(nonNull, Decl(emptyAnonymousObjectNarrowing.ts, 0, 11))
|
||||
|
||||
nonNull;
|
||||
>nonNull : Symbol(nonNull, Decl(emptyAnonymousObjectNarrowing.ts, 0, 11))
|
||||
}
|
||||
else {
|
||||
nonNull;
|
||||
>nonNull : Symbol(nonNull, Decl(emptyAnonymousObjectNarrowing.ts, 0, 11))
|
||||
}
|
||||
|
||||
if (nonNull == undefined) {
|
||||
>nonNull : Symbol(nonNull, Decl(emptyAnonymousObjectNarrowing.ts, 0, 11))
|
||||
>undefined : Symbol(undefined)
|
||||
|
||||
nonNull;
|
||||
>nonNull : Symbol(nonNull, Decl(emptyAnonymousObjectNarrowing.ts, 0, 11))
|
||||
}
|
||||
else {
|
||||
nonNull;
|
||||
>nonNull : Symbol(nonNull, Decl(emptyAnonymousObjectNarrowing.ts, 0, 11))
|
||||
}
|
||||
|
||||
// Repro from #50567
|
||||
const foo = (value: unknown): string => {
|
||||
>foo : Symbol(foo, Decl(emptyAnonymousObjectNarrowing.ts, 64, 5))
|
||||
>value : Symbol(value, Decl(emptyAnonymousObjectNarrowing.ts, 64, 13))
|
||||
|
||||
if (!value) {
|
||||
>value : Symbol(value, Decl(emptyAnonymousObjectNarrowing.ts, 64, 13))
|
||||
|
||||
return 'foo';
|
||||
}
|
||||
if (value === 'xyz') {
|
||||
>value : Symbol(value, Decl(emptyAnonymousObjectNarrowing.ts, 64, 13))
|
||||
|
||||
return value; // Type '{}' is not assignable to type 'string'.
|
||||
>value : Symbol(value, Decl(emptyAnonymousObjectNarrowing.ts, 64, 13))
|
||||
}
|
||||
return '';
|
||||
};
|
||||
|
||||
@ -0,0 +1,152 @@
|
||||
=== tests/cases/compiler/emptyAnonymousObjectNarrowing.ts ===
|
||||
declare let nonNull: {};
|
||||
>nonNull : {}
|
||||
|
||||
if (nonNull === "foo") {
|
||||
>nonNull === "foo" : boolean
|
||||
>nonNull : {}
|
||||
>"foo" : "foo"
|
||||
|
||||
nonNull;
|
||||
>nonNull : "foo"
|
||||
}
|
||||
else {
|
||||
nonNull;
|
||||
>nonNull : {}
|
||||
}
|
||||
|
||||
declare let obj: { a: string };
|
||||
>obj : { a: string; }
|
||||
>a : string
|
||||
|
||||
if (nonNull === obj) {
|
||||
>nonNull === obj : boolean
|
||||
>nonNull : {}
|
||||
>obj : { a: string; }
|
||||
|
||||
nonNull;
|
||||
>nonNull : object
|
||||
}
|
||||
else {
|
||||
nonNull;
|
||||
>nonNull : {}
|
||||
}
|
||||
|
||||
function f1<T>(x: T) {
|
||||
>f1 : <T>(x: T) => void
|
||||
>x : T
|
||||
|
||||
if (nonNull === x) {
|
||||
>nonNull === x : boolean
|
||||
>nonNull : {}
|
||||
>x : T
|
||||
|
||||
nonNull;
|
||||
>nonNull : {}
|
||||
}
|
||||
else {
|
||||
nonNull;
|
||||
>nonNull : {}
|
||||
}
|
||||
}
|
||||
|
||||
function f2<T extends object>(x: T) {
|
||||
>f2 : <T extends object>(x: T) => void
|
||||
>x : T
|
||||
|
||||
if (nonNull === x) {
|
||||
>nonNull === x : boolean
|
||||
>nonNull : {}
|
||||
>x : T
|
||||
|
||||
nonNull;
|
||||
>nonNull : {}
|
||||
}
|
||||
else {
|
||||
nonNull;
|
||||
>nonNull : {}
|
||||
}
|
||||
}
|
||||
|
||||
declare let union: "xyz" | { a: string } | undefined;
|
||||
>union : { a: string; } | "xyz"
|
||||
>a : string
|
||||
|
||||
if (nonNull === union) {
|
||||
>nonNull === union : boolean
|
||||
>nonNull : {}
|
||||
>union : { a: string; } | "xyz"
|
||||
|
||||
nonNull;
|
||||
>nonNull : {}
|
||||
}
|
||||
else {
|
||||
nonNull;
|
||||
>nonNull : {}
|
||||
}
|
||||
|
||||
if (nonNull === undefined) {
|
||||
>nonNull === undefined : boolean
|
||||
>nonNull : {}
|
||||
>undefined : undefined
|
||||
|
||||
nonNull;
|
||||
>nonNull : {}
|
||||
}
|
||||
else {
|
||||
nonNull;
|
||||
>nonNull : {}
|
||||
}
|
||||
|
||||
if (nonNull === null) {
|
||||
>nonNull === null : boolean
|
||||
>nonNull : {}
|
||||
>null : null
|
||||
|
||||
nonNull;
|
||||
>nonNull : {}
|
||||
}
|
||||
else {
|
||||
nonNull;
|
||||
>nonNull : {}
|
||||
}
|
||||
|
||||
if (nonNull == undefined) {
|
||||
>nonNull == undefined : boolean
|
||||
>nonNull : {}
|
||||
>undefined : undefined
|
||||
|
||||
nonNull;
|
||||
>nonNull : {}
|
||||
}
|
||||
else {
|
||||
nonNull;
|
||||
>nonNull : {}
|
||||
}
|
||||
|
||||
// Repro from #50567
|
||||
const foo = (value: unknown): string => {
|
||||
>foo : (value: unknown) => string
|
||||
>(value: unknown): string => { if (!value) { return 'foo'; } if (value === 'xyz') { return value; // Type '{}' is not assignable to type 'string'. } return '';} : (value: unknown) => string
|
||||
>value : unknown
|
||||
|
||||
if (!value) {
|
||||
>!value : boolean
|
||||
>value : unknown
|
||||
|
||||
return 'foo';
|
||||
>'foo' : "foo"
|
||||
}
|
||||
if (value === 'xyz') {
|
||||
>value === 'xyz' : boolean
|
||||
>value : unknown
|
||||
>'xyz' : "xyz"
|
||||
|
||||
return value; // Type '{}' is not assignable to type 'string'.
|
||||
>value : "xyz"
|
||||
}
|
||||
return '';
|
||||
>'' : ""
|
||||
|
||||
};
|
||||
|
||||
@ -0,0 +1,139 @@
|
||||
//// [emptyAnonymousObjectNarrowing.ts]
|
||||
declare let nonNull: {};
|
||||
if (nonNull === "foo") {
|
||||
nonNull;
|
||||
}
|
||||
else {
|
||||
nonNull;
|
||||
}
|
||||
|
||||
declare let obj: { a: string };
|
||||
if (nonNull === obj) {
|
||||
nonNull;
|
||||
}
|
||||
else {
|
||||
nonNull;
|
||||
}
|
||||
|
||||
function f1<T>(x: T) {
|
||||
if (nonNull === x) {
|
||||
nonNull;
|
||||
}
|
||||
else {
|
||||
nonNull;
|
||||
}
|
||||
}
|
||||
|
||||
function f2<T extends object>(x: T) {
|
||||
if (nonNull === x) {
|
||||
nonNull;
|
||||
}
|
||||
else {
|
||||
nonNull;
|
||||
}
|
||||
}
|
||||
|
||||
declare let union: "xyz" | { a: string } | undefined;
|
||||
if (nonNull === union) {
|
||||
nonNull;
|
||||
}
|
||||
else {
|
||||
nonNull;
|
||||
}
|
||||
|
||||
if (nonNull === undefined) {
|
||||
nonNull;
|
||||
}
|
||||
else {
|
||||
nonNull;
|
||||
}
|
||||
|
||||
if (nonNull === null) {
|
||||
nonNull;
|
||||
}
|
||||
else {
|
||||
nonNull;
|
||||
}
|
||||
|
||||
if (nonNull == undefined) {
|
||||
nonNull;
|
||||
}
|
||||
else {
|
||||
nonNull;
|
||||
}
|
||||
|
||||
// Repro from #50567
|
||||
const foo = (value: unknown): string => {
|
||||
if (!value) {
|
||||
return 'foo';
|
||||
}
|
||||
if (value === 'xyz') {
|
||||
return value; // Type '{}' is not assignable to type 'string'.
|
||||
}
|
||||
return '';
|
||||
};
|
||||
|
||||
|
||||
//// [emptyAnonymousObjectNarrowing.js]
|
||||
if (nonNull === "foo") {
|
||||
nonNull;
|
||||
}
|
||||
else {
|
||||
nonNull;
|
||||
}
|
||||
if (nonNull === obj) {
|
||||
nonNull;
|
||||
}
|
||||
else {
|
||||
nonNull;
|
||||
}
|
||||
function f1(x) {
|
||||
if (nonNull === x) {
|
||||
nonNull;
|
||||
}
|
||||
else {
|
||||
nonNull;
|
||||
}
|
||||
}
|
||||
function f2(x) {
|
||||
if (nonNull === x) {
|
||||
nonNull;
|
||||
}
|
||||
else {
|
||||
nonNull;
|
||||
}
|
||||
}
|
||||
if (nonNull === union) {
|
||||
nonNull;
|
||||
}
|
||||
else {
|
||||
nonNull;
|
||||
}
|
||||
if (nonNull === undefined) {
|
||||
nonNull;
|
||||
}
|
||||
else {
|
||||
nonNull;
|
||||
}
|
||||
if (nonNull === null) {
|
||||
nonNull;
|
||||
}
|
||||
else {
|
||||
nonNull;
|
||||
}
|
||||
if (nonNull == undefined) {
|
||||
nonNull;
|
||||
}
|
||||
else {
|
||||
nonNull;
|
||||
}
|
||||
// Repro from #50567
|
||||
var foo = function (value) {
|
||||
if (!value) {
|
||||
return 'foo';
|
||||
}
|
||||
if (value === 'xyz') {
|
||||
return value; // Type '{}' is not assignable to type 'string'.
|
||||
}
|
||||
return '';
|
||||
};
|
||||
@ -0,0 +1,139 @@
|
||||
=== tests/cases/compiler/emptyAnonymousObjectNarrowing.ts ===
|
||||
declare let nonNull: {};
|
||||
>nonNull : Symbol(nonNull, Decl(emptyAnonymousObjectNarrowing.ts, 0, 11))
|
||||
|
||||
if (nonNull === "foo") {
|
||||
>nonNull : Symbol(nonNull, Decl(emptyAnonymousObjectNarrowing.ts, 0, 11))
|
||||
|
||||
nonNull;
|
||||
>nonNull : Symbol(nonNull, Decl(emptyAnonymousObjectNarrowing.ts, 0, 11))
|
||||
}
|
||||
else {
|
||||
nonNull;
|
||||
>nonNull : Symbol(nonNull, Decl(emptyAnonymousObjectNarrowing.ts, 0, 11))
|
||||
}
|
||||
|
||||
declare let obj: { a: string };
|
||||
>obj : Symbol(obj, Decl(emptyAnonymousObjectNarrowing.ts, 8, 11))
|
||||
>a : Symbol(a, Decl(emptyAnonymousObjectNarrowing.ts, 8, 18))
|
||||
|
||||
if (nonNull === obj) {
|
||||
>nonNull : Symbol(nonNull, Decl(emptyAnonymousObjectNarrowing.ts, 0, 11))
|
||||
>obj : Symbol(obj, Decl(emptyAnonymousObjectNarrowing.ts, 8, 11))
|
||||
|
||||
nonNull;
|
||||
>nonNull : Symbol(nonNull, Decl(emptyAnonymousObjectNarrowing.ts, 0, 11))
|
||||
}
|
||||
else {
|
||||
nonNull;
|
||||
>nonNull : Symbol(nonNull, Decl(emptyAnonymousObjectNarrowing.ts, 0, 11))
|
||||
}
|
||||
|
||||
function f1<T>(x: T) {
|
||||
>f1 : Symbol(f1, Decl(emptyAnonymousObjectNarrowing.ts, 14, 1))
|
||||
>T : Symbol(T, Decl(emptyAnonymousObjectNarrowing.ts, 16, 12))
|
||||
>x : Symbol(x, Decl(emptyAnonymousObjectNarrowing.ts, 16, 15))
|
||||
>T : Symbol(T, Decl(emptyAnonymousObjectNarrowing.ts, 16, 12))
|
||||
|
||||
if (nonNull === x) {
|
||||
>nonNull : Symbol(nonNull, Decl(emptyAnonymousObjectNarrowing.ts, 0, 11))
|
||||
>x : Symbol(x, Decl(emptyAnonymousObjectNarrowing.ts, 16, 15))
|
||||
|
||||
nonNull;
|
||||
>nonNull : Symbol(nonNull, Decl(emptyAnonymousObjectNarrowing.ts, 0, 11))
|
||||
}
|
||||
else {
|
||||
nonNull;
|
||||
>nonNull : Symbol(nonNull, Decl(emptyAnonymousObjectNarrowing.ts, 0, 11))
|
||||
}
|
||||
}
|
||||
|
||||
function f2<T extends object>(x: T) {
|
||||
>f2 : Symbol(f2, Decl(emptyAnonymousObjectNarrowing.ts, 23, 1))
|
||||
>T : Symbol(T, Decl(emptyAnonymousObjectNarrowing.ts, 25, 12))
|
||||
>x : Symbol(x, Decl(emptyAnonymousObjectNarrowing.ts, 25, 30))
|
||||
>T : Symbol(T, Decl(emptyAnonymousObjectNarrowing.ts, 25, 12))
|
||||
|
||||
if (nonNull === x) {
|
||||
>nonNull : Symbol(nonNull, Decl(emptyAnonymousObjectNarrowing.ts, 0, 11))
|
||||
>x : Symbol(x, Decl(emptyAnonymousObjectNarrowing.ts, 25, 30))
|
||||
|
||||
nonNull;
|
||||
>nonNull : Symbol(nonNull, Decl(emptyAnonymousObjectNarrowing.ts, 0, 11))
|
||||
}
|
||||
else {
|
||||
nonNull;
|
||||
>nonNull : Symbol(nonNull, Decl(emptyAnonymousObjectNarrowing.ts, 0, 11))
|
||||
}
|
||||
}
|
||||
|
||||
declare let union: "xyz" | { a: string } | undefined;
|
||||
>union : Symbol(union, Decl(emptyAnonymousObjectNarrowing.ts, 34, 11))
|
||||
>a : Symbol(a, Decl(emptyAnonymousObjectNarrowing.ts, 34, 28))
|
||||
|
||||
if (nonNull === union) {
|
||||
>nonNull : Symbol(nonNull, Decl(emptyAnonymousObjectNarrowing.ts, 0, 11))
|
||||
>union : Symbol(union, Decl(emptyAnonymousObjectNarrowing.ts, 34, 11))
|
||||
|
||||
nonNull;
|
||||
>nonNull : Symbol(nonNull, Decl(emptyAnonymousObjectNarrowing.ts, 0, 11))
|
||||
}
|
||||
else {
|
||||
nonNull;
|
||||
>nonNull : Symbol(nonNull, Decl(emptyAnonymousObjectNarrowing.ts, 0, 11))
|
||||
}
|
||||
|
||||
if (nonNull === undefined) {
|
||||
>nonNull : Symbol(nonNull, Decl(emptyAnonymousObjectNarrowing.ts, 0, 11))
|
||||
>undefined : Symbol(undefined)
|
||||
|
||||
nonNull;
|
||||
>nonNull : Symbol(nonNull, Decl(emptyAnonymousObjectNarrowing.ts, 0, 11))
|
||||
}
|
||||
else {
|
||||
nonNull;
|
||||
>nonNull : Symbol(nonNull, Decl(emptyAnonymousObjectNarrowing.ts, 0, 11))
|
||||
}
|
||||
|
||||
if (nonNull === null) {
|
||||
>nonNull : Symbol(nonNull, Decl(emptyAnonymousObjectNarrowing.ts, 0, 11))
|
||||
|
||||
nonNull;
|
||||
>nonNull : Symbol(nonNull, Decl(emptyAnonymousObjectNarrowing.ts, 0, 11))
|
||||
}
|
||||
else {
|
||||
nonNull;
|
||||
>nonNull : Symbol(nonNull, Decl(emptyAnonymousObjectNarrowing.ts, 0, 11))
|
||||
}
|
||||
|
||||
if (nonNull == undefined) {
|
||||
>nonNull : Symbol(nonNull, Decl(emptyAnonymousObjectNarrowing.ts, 0, 11))
|
||||
>undefined : Symbol(undefined)
|
||||
|
||||
nonNull;
|
||||
>nonNull : Symbol(nonNull, Decl(emptyAnonymousObjectNarrowing.ts, 0, 11))
|
||||
}
|
||||
else {
|
||||
nonNull;
|
||||
>nonNull : Symbol(nonNull, Decl(emptyAnonymousObjectNarrowing.ts, 0, 11))
|
||||
}
|
||||
|
||||
// Repro from #50567
|
||||
const foo = (value: unknown): string => {
|
||||
>foo : Symbol(foo, Decl(emptyAnonymousObjectNarrowing.ts, 64, 5))
|
||||
>value : Symbol(value, Decl(emptyAnonymousObjectNarrowing.ts, 64, 13))
|
||||
|
||||
if (!value) {
|
||||
>value : Symbol(value, Decl(emptyAnonymousObjectNarrowing.ts, 64, 13))
|
||||
|
||||
return 'foo';
|
||||
}
|
||||
if (value === 'xyz') {
|
||||
>value : Symbol(value, Decl(emptyAnonymousObjectNarrowing.ts, 64, 13))
|
||||
|
||||
return value; // Type '{}' is not assignable to type 'string'.
|
||||
>value : Symbol(value, Decl(emptyAnonymousObjectNarrowing.ts, 64, 13))
|
||||
}
|
||||
return '';
|
||||
};
|
||||
|
||||
@ -0,0 +1,152 @@
|
||||
=== tests/cases/compiler/emptyAnonymousObjectNarrowing.ts ===
|
||||
declare let nonNull: {};
|
||||
>nonNull : {}
|
||||
|
||||
if (nonNull === "foo") {
|
||||
>nonNull === "foo" : boolean
|
||||
>nonNull : {}
|
||||
>"foo" : "foo"
|
||||
|
||||
nonNull;
|
||||
>nonNull : "foo"
|
||||
}
|
||||
else {
|
||||
nonNull;
|
||||
>nonNull : {}
|
||||
}
|
||||
|
||||
declare let obj: { a: string };
|
||||
>obj : { a: string; }
|
||||
>a : string
|
||||
|
||||
if (nonNull === obj) {
|
||||
>nonNull === obj : boolean
|
||||
>nonNull : {}
|
||||
>obj : { a: string; }
|
||||
|
||||
nonNull;
|
||||
>nonNull : object
|
||||
}
|
||||
else {
|
||||
nonNull;
|
||||
>nonNull : {}
|
||||
}
|
||||
|
||||
function f1<T>(x: T) {
|
||||
>f1 : <T>(x: T) => void
|
||||
>x : T
|
||||
|
||||
if (nonNull === x) {
|
||||
>nonNull === x : boolean
|
||||
>nonNull : {}
|
||||
>x : T
|
||||
|
||||
nonNull;
|
||||
>nonNull : {}
|
||||
}
|
||||
else {
|
||||
nonNull;
|
||||
>nonNull : {}
|
||||
}
|
||||
}
|
||||
|
||||
function f2<T extends object>(x: T) {
|
||||
>f2 : <T extends object>(x: T) => void
|
||||
>x : T
|
||||
|
||||
if (nonNull === x) {
|
||||
>nonNull === x : boolean
|
||||
>nonNull : {}
|
||||
>x : T
|
||||
|
||||
nonNull;
|
||||
>nonNull : {}
|
||||
}
|
||||
else {
|
||||
nonNull;
|
||||
>nonNull : {}
|
||||
}
|
||||
}
|
||||
|
||||
declare let union: "xyz" | { a: string } | undefined;
|
||||
>union : { a: string; } | "xyz" | undefined
|
||||
>a : string
|
||||
|
||||
if (nonNull === union) {
|
||||
>nonNull === union : boolean
|
||||
>nonNull : {}
|
||||
>union : { a: string; } | "xyz" | undefined
|
||||
|
||||
nonNull;
|
||||
>nonNull : {}
|
||||
}
|
||||
else {
|
||||
nonNull;
|
||||
>nonNull : {}
|
||||
}
|
||||
|
||||
if (nonNull === undefined) {
|
||||
>nonNull === undefined : boolean
|
||||
>nonNull : {}
|
||||
>undefined : undefined
|
||||
|
||||
nonNull;
|
||||
>nonNull : never
|
||||
}
|
||||
else {
|
||||
nonNull;
|
||||
>nonNull : {}
|
||||
}
|
||||
|
||||
if (nonNull === null) {
|
||||
>nonNull === null : boolean
|
||||
>nonNull : {}
|
||||
>null : null
|
||||
|
||||
nonNull;
|
||||
>nonNull : never
|
||||
}
|
||||
else {
|
||||
nonNull;
|
||||
>nonNull : {}
|
||||
}
|
||||
|
||||
if (nonNull == undefined) {
|
||||
>nonNull == undefined : boolean
|
||||
>nonNull : {}
|
||||
>undefined : undefined
|
||||
|
||||
nonNull;
|
||||
>nonNull : never
|
||||
}
|
||||
else {
|
||||
nonNull;
|
||||
>nonNull : {}
|
||||
}
|
||||
|
||||
// Repro from #50567
|
||||
const foo = (value: unknown): string => {
|
||||
>foo : (value: unknown) => string
|
||||
>(value: unknown): string => { if (!value) { return 'foo'; } if (value === 'xyz') { return value; // Type '{}' is not assignable to type 'string'. } return '';} : (value: unknown) => string
|
||||
>value : unknown
|
||||
|
||||
if (!value) {
|
||||
>!value : boolean
|
||||
>value : unknown
|
||||
|
||||
return 'foo';
|
||||
>'foo' : "foo"
|
||||
}
|
||||
if (value === 'xyz') {
|
||||
>value === 'xyz' : boolean
|
||||
>value : {}
|
||||
>'xyz' : "xyz"
|
||||
|
||||
return value; // Type '{}' is not assignable to type 'string'.
|
||||
>value : "xyz"
|
||||
}
|
||||
return '';
|
||||
>'' : ""
|
||||
|
||||
};
|
||||
|
||||
75
tests/cases/compiler/emptyAnonymousObjectNarrowing.ts
Normal file
75
tests/cases/compiler/emptyAnonymousObjectNarrowing.ts
Normal file
@ -0,0 +1,75 @@
|
||||
// @strictNullChecks: true,false
|
||||
|
||||
declare let nonNull: {};
|
||||
if (nonNull === "foo") {
|
||||
nonNull;
|
||||
}
|
||||
else {
|
||||
nonNull;
|
||||
}
|
||||
|
||||
declare let obj: { a: string };
|
||||
if (nonNull === obj) {
|
||||
nonNull;
|
||||
}
|
||||
else {
|
||||
nonNull;
|
||||
}
|
||||
|
||||
function f1<T>(x: T) {
|
||||
if (nonNull === x) {
|
||||
nonNull;
|
||||
}
|
||||
else {
|
||||
nonNull;
|
||||
}
|
||||
}
|
||||
|
||||
function f2<T extends object>(x: T) {
|
||||
if (nonNull === x) {
|
||||
nonNull;
|
||||
}
|
||||
else {
|
||||
nonNull;
|
||||
}
|
||||
}
|
||||
|
||||
declare let union: "xyz" | { a: string } | undefined;
|
||||
if (nonNull === union) {
|
||||
nonNull;
|
||||
}
|
||||
else {
|
||||
nonNull;
|
||||
}
|
||||
|
||||
if (nonNull === undefined) {
|
||||
nonNull;
|
||||
}
|
||||
else {
|
||||
nonNull;
|
||||
}
|
||||
|
||||
if (nonNull === null) {
|
||||
nonNull;
|
||||
}
|
||||
else {
|
||||
nonNull;
|
||||
}
|
||||
|
||||
if (nonNull == undefined) {
|
||||
nonNull;
|
||||
}
|
||||
else {
|
||||
nonNull;
|
||||
}
|
||||
|
||||
// Repro from #50567
|
||||
const foo = (value: unknown): string => {
|
||||
if (!value) {
|
||||
return 'foo';
|
||||
}
|
||||
if (value === 'xyz') {
|
||||
return value; // Type '{}' is not assignable to type 'string'.
|
||||
}
|
||||
return '';
|
||||
};
|
||||
Loading…
x
Reference in New Issue
Block a user