为什么 TypesScript 允许无效比较 - boolean === undefined?

coo*_*ood 4 javascript typescript eslint tslint typescript-typings

面对TS的奇怪行为。

const isItLanding = false;

if (isItLanding === undefined) { // valid
  return ...;
}
Run Code Online (Sandbox Code Playgroud)

但在这儿

const isItLanding = 1;

if (isItLanding === 'undefined') { // error
  return ...;
}
Run Code Online (Sandbox Code Playgroud)

为什么 TS 不保证不会写入无效比较?我怎样才能改变这种行为?

我的 TS 配置如下:

{
  "compilerOptions": {
    "strict": true,
    "target": "esnext",
    "lib": ["dom", "dom.iterable", "esnext"],
    "allowJs": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "noEmit": true,
    "esModuleInterop": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "importsNotUsedAsValues": "error",
    "allowSyntheticDefaultImports": true,
    "incremental": true,
    "tsBuildInfoFile": ".next/cache/.tscache/",
    "jsx": "preserve",
    "sourceMap": true,
    "baseUrl": ".",
    "paths": {
      "~/*": ["src/*"],
      "test-utils": ["./src/client/test-utils"]
    }
  },
  "exclude": ["node_modules", "cypress"]
}
Run Code Online (Sandbox Code Playgroud)

小智 6

简短回答:TypeScript 有意允许任何类型与“null”或“undefined”进行比较

这是允许的,因为布尔值可以是未定义的

在 TypeScript 中,布尔值可以容纳四个值truefalseundefinednull,这意味着根据定义,可能存在比较实际上为 true 的情况。

let bool: boolean = true;
bool = false;
bool = null;
bool = undefined;
//All compiles without an issue

if(bool === undefined){
   console.log("You will see me!");
}
Run Code Online (Sandbox Code Playgroud)

如何保证boolean只能为true或false?

在你的 TS 配置中,你可以将一个标志设置strictNullCheckstrue,这样当类型被检查时undefined,并且null将被考虑在内。一旦设置此标志,上面的代码将返回错误。

let bool: boolean = true;
bool = false;
bool = null; //Error > Type 'null' is not assignable to type 'boolean'.
bool = undefined; //Error > Type 'undefined' is not assignable to type 'boolean'.
Run Code Online (Sandbox Code Playgroud)

为什么将标志更改为 null 或 undefined 后仍然允许比较?

考虑下面的代码:
const bool: boolean = false;

if(bool === undefined){
   console.log("I am undefined!");
}
if(bool === null){
   console.log("I am null!");
}

console.log("It compiled?");
Run Code Online (Sandbox Code Playgroud)

为什么这些 if 语句都不返回错误,即使它们总是 false?

答案可能会让某些人失望,但原因很简单:它是有意设计的,您可以将任何类型与“null”或“undefined”进行比较。这就是语言的构造方式,即允许防御性编程。如果有足够的需求,未来可能会改变,但我个人认为永远不会改变。

if(12 === undefined){
   console.log("impossible isn't it?");
}
if("ab" === null){
   console.log("no way it will ever be true!");
}
if(false === undefined){
   console.log("never ever");
}

/*
if(12 === "ab") 
^this would error as comparison to different types is allowed only with null and undefined
*/

console.log("Yet, it will indeed compile");
Run Code Online (Sandbox Code Playgroud)