mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-06 02:33:53 -06:00
Merge pull request #23782 from Microsoft/controlFlowNullTypeAndLiteral
Control flow for null type vs. literal
This commit is contained in:
commit
83bc70dd63
@ -13690,7 +13690,7 @@ namespace ts {
|
||||
const doubleEquals = operator === SyntaxKind.EqualsEqualsToken || operator === SyntaxKind.ExclamationEqualsToken;
|
||||
const facts = doubleEquals ?
|
||||
assumeTrue ? TypeFacts.EQUndefinedOrNull : TypeFacts.NEUndefinedOrNull :
|
||||
value.kind === SyntaxKind.NullKeyword ?
|
||||
valueType.flags & TypeFlags.Null ?
|
||||
assumeTrue ? TypeFacts.EQNull : TypeFacts.NENull :
|
||||
assumeTrue ? TypeFacts.EQUndefined : TypeFacts.NEUndefined;
|
||||
return getTypeWithFacts(type, facts);
|
||||
|
||||
@ -0,0 +1,36 @@
|
||||
tests/cases/compiler/controlFlowNullTypeAndLiteral.ts(15,12): error TS2345: Argument of type 'null' is not assignable to parameter of type 'number'.
|
||||
tests/cases/compiler/controlFlowNullTypeAndLiteral.ts(17,12): error TS2345: Argument of type 'null' is not assignable to parameter of type 'number'.
|
||||
tests/cases/compiler/controlFlowNullTypeAndLiteral.ts(21,15): error TS2322: Type 'null' is not assignable to type 'string'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/controlFlowNullTypeAndLiteral.ts (3 errors) ====
|
||||
// Repros from #23771
|
||||
|
||||
const myNull: null = null;
|
||||
const objWithValMaybeNull: { val: number | null } = { val: 1 };
|
||||
const addOne = function (num: number) {
|
||||
return num + 1;
|
||||
}
|
||||
|
||||
if (objWithValMaybeNull.val !== null)
|
||||
addOne(objWithValMaybeNull.val);
|
||||
if (objWithValMaybeNull.val !== myNull)
|
||||
addOne(objWithValMaybeNull.val);
|
||||
|
||||
if (objWithValMaybeNull.val === null)
|
||||
addOne(objWithValMaybeNull.val); // Error
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2345: Argument of type 'null' is not assignable to parameter of type 'number'.
|
||||
if (objWithValMaybeNull.val === myNull)
|
||||
addOne(objWithValMaybeNull.val); // Error
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2345: Argument of type 'null' is not assignable to parameter of type 'number'.
|
||||
|
||||
function f(x: number | null) {
|
||||
if(x === myNull) {
|
||||
const s: string = x; // Error
|
||||
~
|
||||
!!! error TS2322: Type 'null' is not assignable to type 'string'.
|
||||
}
|
||||
}
|
||||
|
||||
47
tests/baselines/reference/controlFlowNullTypeAndLiteral.js
Normal file
47
tests/baselines/reference/controlFlowNullTypeAndLiteral.js
Normal file
@ -0,0 +1,47 @@
|
||||
//// [controlFlowNullTypeAndLiteral.ts]
|
||||
// Repros from #23771
|
||||
|
||||
const myNull: null = null;
|
||||
const objWithValMaybeNull: { val: number | null } = { val: 1 };
|
||||
const addOne = function (num: number) {
|
||||
return num + 1;
|
||||
}
|
||||
|
||||
if (objWithValMaybeNull.val !== null)
|
||||
addOne(objWithValMaybeNull.val);
|
||||
if (objWithValMaybeNull.val !== myNull)
|
||||
addOne(objWithValMaybeNull.val);
|
||||
|
||||
if (objWithValMaybeNull.val === null)
|
||||
addOne(objWithValMaybeNull.val); // Error
|
||||
if (objWithValMaybeNull.val === myNull)
|
||||
addOne(objWithValMaybeNull.val); // Error
|
||||
|
||||
function f(x: number | null) {
|
||||
if(x === myNull) {
|
||||
const s: string = x; // Error
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//// [controlFlowNullTypeAndLiteral.js]
|
||||
"use strict";
|
||||
// Repros from #23771
|
||||
var myNull = null;
|
||||
var objWithValMaybeNull = { val: 1 };
|
||||
var addOne = function (num) {
|
||||
return num + 1;
|
||||
};
|
||||
if (objWithValMaybeNull.val !== null)
|
||||
addOne(objWithValMaybeNull.val);
|
||||
if (objWithValMaybeNull.val !== myNull)
|
||||
addOne(objWithValMaybeNull.val);
|
||||
if (objWithValMaybeNull.val === null)
|
||||
addOne(objWithValMaybeNull.val); // Error
|
||||
if (objWithValMaybeNull.val === myNull)
|
||||
addOne(objWithValMaybeNull.val); // Error
|
||||
function f(x) {
|
||||
if (x === myNull) {
|
||||
var s = x; // Error
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,79 @@
|
||||
=== tests/cases/compiler/controlFlowNullTypeAndLiteral.ts ===
|
||||
// Repros from #23771
|
||||
|
||||
const myNull: null = null;
|
||||
>myNull : Symbol(myNull, Decl(controlFlowNullTypeAndLiteral.ts, 2, 5))
|
||||
|
||||
const objWithValMaybeNull: { val: number | null } = { val: 1 };
|
||||
>objWithValMaybeNull : Symbol(objWithValMaybeNull, Decl(controlFlowNullTypeAndLiteral.ts, 3, 5))
|
||||
>val : Symbol(val, Decl(controlFlowNullTypeAndLiteral.ts, 3, 28))
|
||||
>val : Symbol(val, Decl(controlFlowNullTypeAndLiteral.ts, 3, 53))
|
||||
|
||||
const addOne = function (num: number) {
|
||||
>addOne : Symbol(addOne, Decl(controlFlowNullTypeAndLiteral.ts, 4, 5))
|
||||
>num : Symbol(num, Decl(controlFlowNullTypeAndLiteral.ts, 4, 25))
|
||||
|
||||
return num + 1;
|
||||
>num : Symbol(num, Decl(controlFlowNullTypeAndLiteral.ts, 4, 25))
|
||||
}
|
||||
|
||||
if (objWithValMaybeNull.val !== null)
|
||||
>objWithValMaybeNull.val : Symbol(val, Decl(controlFlowNullTypeAndLiteral.ts, 3, 28))
|
||||
>objWithValMaybeNull : Symbol(objWithValMaybeNull, Decl(controlFlowNullTypeAndLiteral.ts, 3, 5))
|
||||
>val : Symbol(val, Decl(controlFlowNullTypeAndLiteral.ts, 3, 28))
|
||||
|
||||
addOne(objWithValMaybeNull.val);
|
||||
>addOne : Symbol(addOne, Decl(controlFlowNullTypeAndLiteral.ts, 4, 5))
|
||||
>objWithValMaybeNull.val : Symbol(val, Decl(controlFlowNullTypeAndLiteral.ts, 3, 28))
|
||||
>objWithValMaybeNull : Symbol(objWithValMaybeNull, Decl(controlFlowNullTypeAndLiteral.ts, 3, 5))
|
||||
>val : Symbol(val, Decl(controlFlowNullTypeAndLiteral.ts, 3, 28))
|
||||
|
||||
if (objWithValMaybeNull.val !== myNull)
|
||||
>objWithValMaybeNull.val : Symbol(val, Decl(controlFlowNullTypeAndLiteral.ts, 3, 28))
|
||||
>objWithValMaybeNull : Symbol(objWithValMaybeNull, Decl(controlFlowNullTypeAndLiteral.ts, 3, 5))
|
||||
>val : Symbol(val, Decl(controlFlowNullTypeAndLiteral.ts, 3, 28))
|
||||
>myNull : Symbol(myNull, Decl(controlFlowNullTypeAndLiteral.ts, 2, 5))
|
||||
|
||||
addOne(objWithValMaybeNull.val);
|
||||
>addOne : Symbol(addOne, Decl(controlFlowNullTypeAndLiteral.ts, 4, 5))
|
||||
>objWithValMaybeNull.val : Symbol(val, Decl(controlFlowNullTypeAndLiteral.ts, 3, 28))
|
||||
>objWithValMaybeNull : Symbol(objWithValMaybeNull, Decl(controlFlowNullTypeAndLiteral.ts, 3, 5))
|
||||
>val : Symbol(val, Decl(controlFlowNullTypeAndLiteral.ts, 3, 28))
|
||||
|
||||
if (objWithValMaybeNull.val === null)
|
||||
>objWithValMaybeNull.val : Symbol(val, Decl(controlFlowNullTypeAndLiteral.ts, 3, 28))
|
||||
>objWithValMaybeNull : Symbol(objWithValMaybeNull, Decl(controlFlowNullTypeAndLiteral.ts, 3, 5))
|
||||
>val : Symbol(val, Decl(controlFlowNullTypeAndLiteral.ts, 3, 28))
|
||||
|
||||
addOne(objWithValMaybeNull.val); // Error
|
||||
>addOne : Symbol(addOne, Decl(controlFlowNullTypeAndLiteral.ts, 4, 5))
|
||||
>objWithValMaybeNull.val : Symbol(val, Decl(controlFlowNullTypeAndLiteral.ts, 3, 28))
|
||||
>objWithValMaybeNull : Symbol(objWithValMaybeNull, Decl(controlFlowNullTypeAndLiteral.ts, 3, 5))
|
||||
>val : Symbol(val, Decl(controlFlowNullTypeAndLiteral.ts, 3, 28))
|
||||
|
||||
if (objWithValMaybeNull.val === myNull)
|
||||
>objWithValMaybeNull.val : Symbol(val, Decl(controlFlowNullTypeAndLiteral.ts, 3, 28))
|
||||
>objWithValMaybeNull : Symbol(objWithValMaybeNull, Decl(controlFlowNullTypeAndLiteral.ts, 3, 5))
|
||||
>val : Symbol(val, Decl(controlFlowNullTypeAndLiteral.ts, 3, 28))
|
||||
>myNull : Symbol(myNull, Decl(controlFlowNullTypeAndLiteral.ts, 2, 5))
|
||||
|
||||
addOne(objWithValMaybeNull.val); // Error
|
||||
>addOne : Symbol(addOne, Decl(controlFlowNullTypeAndLiteral.ts, 4, 5))
|
||||
>objWithValMaybeNull.val : Symbol(val, Decl(controlFlowNullTypeAndLiteral.ts, 3, 28))
|
||||
>objWithValMaybeNull : Symbol(objWithValMaybeNull, Decl(controlFlowNullTypeAndLiteral.ts, 3, 5))
|
||||
>val : Symbol(val, Decl(controlFlowNullTypeAndLiteral.ts, 3, 28))
|
||||
|
||||
function f(x: number | null) {
|
||||
>f : Symbol(f, Decl(controlFlowNullTypeAndLiteral.ts, 16, 36))
|
||||
>x : Symbol(x, Decl(controlFlowNullTypeAndLiteral.ts, 18, 11))
|
||||
|
||||
if(x === myNull) {
|
||||
>x : Symbol(x, Decl(controlFlowNullTypeAndLiteral.ts, 18, 11))
|
||||
>myNull : Symbol(myNull, Decl(controlFlowNullTypeAndLiteral.ts, 2, 5))
|
||||
|
||||
const s: string = x; // Error
|
||||
>s : Symbol(s, Decl(controlFlowNullTypeAndLiteral.ts, 20, 13))
|
||||
>x : Symbol(x, Decl(controlFlowNullTypeAndLiteral.ts, 18, 11))
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,99 @@
|
||||
=== tests/cases/compiler/controlFlowNullTypeAndLiteral.ts ===
|
||||
// Repros from #23771
|
||||
|
||||
const myNull: null = null;
|
||||
>myNull : null
|
||||
>null : null
|
||||
>null : null
|
||||
|
||||
const objWithValMaybeNull: { val: number | null } = { val: 1 };
|
||||
>objWithValMaybeNull : { val: number | null; }
|
||||
>val : number | null
|
||||
>null : null
|
||||
>{ val: 1 } : { val: number; }
|
||||
>val : number
|
||||
>1 : 1
|
||||
|
||||
const addOne = function (num: number) {
|
||||
>addOne : (num: number) => number
|
||||
>function (num: number) { return num + 1;} : (num: number) => number
|
||||
>num : number
|
||||
|
||||
return num + 1;
|
||||
>num + 1 : number
|
||||
>num : number
|
||||
>1 : 1
|
||||
}
|
||||
|
||||
if (objWithValMaybeNull.val !== null)
|
||||
>objWithValMaybeNull.val !== null : boolean
|
||||
>objWithValMaybeNull.val : number | null
|
||||
>objWithValMaybeNull : { val: number | null; }
|
||||
>val : number | null
|
||||
>null : null
|
||||
|
||||
addOne(objWithValMaybeNull.val);
|
||||
>addOne(objWithValMaybeNull.val) : number
|
||||
>addOne : (num: number) => number
|
||||
>objWithValMaybeNull.val : number
|
||||
>objWithValMaybeNull : { val: number | null; }
|
||||
>val : number
|
||||
|
||||
if (objWithValMaybeNull.val !== myNull)
|
||||
>objWithValMaybeNull.val !== myNull : boolean
|
||||
>objWithValMaybeNull.val : number | null
|
||||
>objWithValMaybeNull : { val: number | null; }
|
||||
>val : number | null
|
||||
>myNull : null
|
||||
|
||||
addOne(objWithValMaybeNull.val);
|
||||
>addOne(objWithValMaybeNull.val) : number
|
||||
>addOne : (num: number) => number
|
||||
>objWithValMaybeNull.val : number
|
||||
>objWithValMaybeNull : { val: number | null; }
|
||||
>val : number
|
||||
|
||||
if (objWithValMaybeNull.val === null)
|
||||
>objWithValMaybeNull.val === null : boolean
|
||||
>objWithValMaybeNull.val : number | null
|
||||
>objWithValMaybeNull : { val: number | null; }
|
||||
>val : number | null
|
||||
>null : null
|
||||
|
||||
addOne(objWithValMaybeNull.val); // Error
|
||||
>addOne(objWithValMaybeNull.val) : number
|
||||
>addOne : (num: number) => number
|
||||
>objWithValMaybeNull.val : null
|
||||
>objWithValMaybeNull : { val: number | null; }
|
||||
>val : null
|
||||
|
||||
if (objWithValMaybeNull.val === myNull)
|
||||
>objWithValMaybeNull.val === myNull : boolean
|
||||
>objWithValMaybeNull.val : number | null
|
||||
>objWithValMaybeNull : { val: number | null; }
|
||||
>val : number | null
|
||||
>myNull : null
|
||||
|
||||
addOne(objWithValMaybeNull.val); // Error
|
||||
>addOne(objWithValMaybeNull.val) : number
|
||||
>addOne : (num: number) => number
|
||||
>objWithValMaybeNull.val : null
|
||||
>objWithValMaybeNull : { val: number | null; }
|
||||
>val : null
|
||||
|
||||
function f(x: number | null) {
|
||||
>f : (x: number | null) => void
|
||||
>x : number | null
|
||||
>null : null
|
||||
|
||||
if(x === myNull) {
|
||||
>x === myNull : boolean
|
||||
>x : number | null
|
||||
>myNull : null
|
||||
|
||||
const s: string = x; // Error
|
||||
>s : string
|
||||
>x : null
|
||||
}
|
||||
}
|
||||
|
||||
25
tests/cases/compiler/controlFlowNullTypeAndLiteral.ts
Normal file
25
tests/cases/compiler/controlFlowNullTypeAndLiteral.ts
Normal file
@ -0,0 +1,25 @@
|
||||
// @strict: true
|
||||
|
||||
// Repros from #23771
|
||||
|
||||
const myNull: null = null;
|
||||
const objWithValMaybeNull: { val: number | null } = { val: 1 };
|
||||
const addOne = function (num: number) {
|
||||
return num + 1;
|
||||
}
|
||||
|
||||
if (objWithValMaybeNull.val !== null)
|
||||
addOne(objWithValMaybeNull.val);
|
||||
if (objWithValMaybeNull.val !== myNull)
|
||||
addOne(objWithValMaybeNull.val);
|
||||
|
||||
if (objWithValMaybeNull.val === null)
|
||||
addOne(objWithValMaybeNull.val); // Error
|
||||
if (objWithValMaybeNull.val === myNull)
|
||||
addOne(objWithValMaybeNull.val); // Error
|
||||
|
||||
function f(x: number | null) {
|
||||
if(x === myNull) {
|
||||
const s: string = x; // Error
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user