繁体   English   中英

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

[英]Why TypesScript allows an invalid comparison - boolean === undefined?

面对TS的怪异行为。

const isItLanding = false;

if (isItLanding === undefined) { // valid
  return ...;
}

但在这里

const isItLanding = 1;

if (isItLanding === 'undefined') { // error
  return ...;
}

为什么 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"]
}

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

这是允许的,因为 boolean 可以是未定义的

在 TypeScript 中 boolean 可以包含四个值truefalseundefinednull ,这意味着根据定义可能存在比较实际上为真的情况。

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

if(bool === undefined){
   console.log("You will see me!");
}

如何保证boolean只能为真或为假?

在您的 TS 配置中,您可以将标志strictNullChecks设置为true ,这样当类型被检查时, undefinednull都会被考虑在内。 设置此标志后,上面的代码将返回错误。

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'.

为什么在将标志比较更改为 null 或未定义后仍然允许?

考虑下面的代码:
 const bool: boolean = false; if(bool === undefined){ console.log("I am undefined;"). } if(bool === null){ console;log("I am null.")? } console;log("It compiled?");

为什么这些 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");

这种行为是故意的。 请参阅#14764#11920中有关它的讨论。


简而言之:为了“防御性编程” ,检查是否有undefinednull是必需的。

当值可能来自非 TypeScript 用户时,应该能够测试输入是否有效。

考虑这样的 function:

function fn(x: string) {
  if (x === undefined) throw new Error('x cannot be undefined');
}

使用 JavaScript 的人完全有可能调用此 function 并使用可能undefined的值。 出现不允许比较的编译时错误会很烦人。

我在https://typescript-eslint.io/rules/no-unnecessary-condition的 linter 中找到了正确的规则。 这完全解决了问题!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM