简体   繁体   English

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

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

Faced with the strange behavior of TS.面对TS的怪异行为。

const isItLanding = false;

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

But here但在这里

const isItLanding = 1;

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

Why doesn't TS insure against writing invalid comparisons?为什么 TS 不确保不会写入无效比较? And how can I change this behavior?我怎样才能改变这种行为?

My TS config looks like:我的 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"]
}

Short answer: TypeScript intentionally allows any type to be compared to "null" or "undefined"简短回答:TypeScript 有意允许将任何类型与“null”或“undefined”进行比较

It is allowed because boolean can be undefined这是允许的,因为 boolean 可以是未定义的

In TypeScript boolean can hold four values true , false , undefined and null , what means that by definition there might be a case where the comparison will in fact be true.在 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!");
}

How to ensure that boolean can only be true or false?如何保证boolean只能为真或为假?

In your TS config you can set a flag strictNullChecks to true , this way when type is checked both undefined and null will be taken into account.在您的 TS 配置中,您可以将标志strictNullChecks设置为true ,这样当类型被检查时, undefinednull都会被考虑在内。 Once this flag is set, the code above will return an error.设置此标志后,上面的代码将返回错误。

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

Why after changing the flag comparison to null or undefined is still allowed?为什么在将标志比较更改为 null 或未定义后仍然允许?

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

Why neither of these if statements return an error, even if they are always false?为什么这些 if 语句都不返回错误,即使它们始终为 false?

The answer might be disappointing to some, but the reason is simple: It is intentionally designed that you can compare any type to "null" or "undefined" .答案可能会让一些人失望,但原因很简单:它是有意设计的,您可以将任何类型与 "null" 或 "undefined" 进行比较 It's the way the language was constructed, that is to allow defensive programming.这就是语言的构造方式,即允许防御性编程。 It might be changed in the future, if there is enough of demand, but I personally don't think there ever will be.如果有足够的需求,将来可能会改变,但我个人认为永远不会。

 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");

This behavior is intentional.这种行为是故意的。 See discussions about it at #14764 or #11920 .请参阅#14764#11920中有关它的讨论。


In short: Checking if something is undefined or null is needed for the sake of "defensive programming" .简而言之:为了“防御性编程” ,检查是否有undefinednull是必需的。

One should be able to test inputs to be valid to when values might be coming from non-TypeScript users.当值可能来自非 TypeScript 用户时,应该能够测试输入是否有效。

Consider a function like this:考虑这样的 function:

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

Its entirely possible that someone using JavaScript would call this function with a value that might be undefined .使用 JavaScript 的人完全有可能调用此 function 并使用可能undefined的值。 Having a compile time error disallowing the comparison would be annoying.出现不允许比较的编译时错误会很烦人。

I found the right rule in the linter at https://typescript-eslint.io/rules/no-unnecessary-condition .我在https://typescript-eslint.io/rules/no-unnecessary-condition的 linter 中找到了正确的规则。 This completely solves the problem!这完全解决了问题!

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

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