【问题标题】:Is there a way to check for both `null` and `undefined`?有没有办法同时检查“null”和“undefined”?
【发布时间】:2015-05-12 14:37:57
【问题描述】:

由于 TypeScript 是强类型的,简单地使用 if () {} 来检查 nullundefined 听起来不对。

TypeScript 有专门的函数或语法糖吗?

【问题讨论】:

  • Since TypeScript is strongly-typed 我在它的文档中找不到这个,我对此表示怀疑......
  • 推荐阅读最新的不可空类型,这是 Typescript 2,但截至今天已经处于测试阶段。 [不可为空的类型 #7140] (github.com/Microsoft/TypeScript/pull/7140)
  • TypeScript 没有专门的函数来做任何事情。它是一个打字系统和一个转译器,而不是一个库。
  • 正如你所说,只检查if () {} 是不好的,因为0 也是如此。

标签: typescript null-check


【解决方案1】:

使用杂耍检查,您可以一次性测试nullundefined

if (x == null) {

如果您使用严格检查,它只会对设置为 null 的值为真,并且不会对未定义的变量评估为真:

if (x === null) {

您可以使用此示例尝试使用各种值:

var a: number;
var b: number = null;

function check(x, name) {
    if (x == null) {
        console.log(name + ' == null');
    }

    if (x === null) {
        console.log(name + ' === null');
    }

    if (typeof x === 'undefined') {
        console.log(name + ' is undefined');
    }
}

check(a, 'a');
check(b, 'b');

输出

"a == null"

“a 未定义”

“b == null”

“b === null”

【讨论】:

  • 什么是“杂耍检查”?
  • @akapelko 类型是杂耍的地方(即“我们可以让这个类型成为布尔值吗”)。因此,例如,空字符串被视为布尔值 false。杂耍时的一个常见错误是:"false" == false 像“false”这样的非空字符串的计算结果为 true
  • 这是由于 JS 的“类型强制”。
  • @JonGunter 对于真/假if(x) 样式检查是正确的,但不是if(x == null),它只捕获nullundefined。使用var c: number = 0; check(c, 'b'); 检查它不是“nully”、nullundefined
  • @developer - 不完全是,因为if (!x) 会(例如)将数字0 和字符串'' 视为null,而if (x == null) 不会。
【解决方案2】:
if( value ) {
}

如果value 不是,则评估为true

  • null
  • undefined
  • NaN
  • 空字符串''
  • 0
  • false

typescript 包含 javascript 规则。

【讨论】:

  • 如果值是布尔类型怎么办?
  • 你可以结合两个变量,例如。 if(value1 && value2) 检查它们是否都未定义?
  • @RamazanSağır 是的,谢谢我知道,但事实是 0 值是我可以拥有的有效值,我要做的唯一检查是该变量既不是 null 也不是未定义。我已经读到我可以通过使用 val != null 来做到这一点(!= 而不是 !== 也检查未定义的值)
  • 如果启用了 tslint 规则 - "strict-boolean-expressions",此解决方案将不起作用。
  • 如果我们的值是假的,它会评估为假,就像这样简单。
【解决方案3】:

TypeScript 3.7 中,我们现在有 Optional chainingNullish Coalescing 来检查 nullundefined 同时,例如:

let x = foo?.bar.baz();

此代码将检查 foo 是否已定义,否则将返回 undefined

老办法

if(foo != null && foo != undefined) {
   x = foo.bar.baz();
} 

这个:

let x = (foo === null || foo === undefined) ? undefined : foo.bar();

if (foo && foo.bar && foo.bar.baz) { // ... }

使用可选链接将是:

let x = foo?.bar();

if (foo?.bar?.baz) { // ... }

另一个新功能是Nullish Coalescing,例如:

let x = foo ?? bar(); // return foo if it's not null or undefined otherwise calculate bar

老办法:

let x = (foo !== null && foo !== undefined) ?
foo :
bar();

奖金

【讨论】:

【解决方案4】:

TypeScript 是否为此提供了专用的函数或语法糖

TypeScript 完全理解 something == null 的 JavaScript 版本。

TypeScript 将通过此类检查正确排除 nullundefined

更多

https://basarat.gitbook.io/typescript/recap/null-undefined

【讨论】:

  • 我喜欢做两个等于myVar == null。只是另一种选择。
  • == null 是测试 null 和 undefined 的正确方法。 !!something 是 JS 条件中的无用强制(只需使用 something)。 !!something 还将强制 0 和 '' 为 false,如果您正在寻找 null/undefined,这不是您想要做的。
【解决方案5】:

我在打字稿操场上做了不同的测试:

http://www.typescriptlang.org/play/

let a;
let b = null;
let c = "";
var output = "";

if (a == null) output += "a is null or undefined\n";
if (b == null) output += "b is null or undefined\n";
if (c == null) output += "c is null or undefined\n";
if (a != null) output += "a is defined\n";
if (b != null) output += "b is defined\n";
if (c != null) output += "c is defined\n";
if (a) output += "a is defined (2nd method)\n";
if (b) output += "b is defined (2nd method)\n";
if (c) output += "c is defined (2nd method)\n";

console.log(output);

给予:

a is null or undefined
b is null or undefined
c is defined

所以:

  • 检查 (a == null) 是否正确知道 a 是 null 还是未定义
  • 检查 (a != null) 是否正确了解 a 是否已定义
  • 检查 (a) 是否错误以了解 a 是否已定义

【讨论】:

  • 你为什么要使用 TypeScript 游乐场?这里与 TypeScript 没有任何关系。
  • 因为这个问题与 Typescript 有关,所以我试图针对 Typescript 转译器测试不同的建议解决方案。
  • TS 转译器根本不会转换任何代码。
【解决方案6】:

你可以试试

if(!!someValue)

!!

说明

第一个! 会将您的表达式转换为boolean 值。

如果someValue虚假,那么!someValuetrue,如果someValue真实,那么false。这可能会令人困惑。

通过添加另一个!,表达式现在是true 如果someValuetruthyfalse 如果someValuefalsy,这是更容易管理。

讨论

现在,既然if (someValue) 之类的东西会给我同样的结果,我为什么还要用if (!!someValue) 打扰自己呢?

因为!!someValue 恰好是一个布尔表达式,而someValue 绝对可以是任何东西。这种表达式现在可以编写函数(我们需要这些函数),例如:

isSomeValueDefined(): boolean {
  return !!someValue
}

代替:

isSomeValueDefined(): boolean {
  if(someValue) {
    return true
  }
  return false
}

希望对你有帮助。

【讨论】:

  • 那么,如果 someValue 为 'false'(字符串类型),那么 !!someValue 为 false(布尔类型)?
  • 我猜你可能会这么说。这个技术正是为了避免出现这种混乱。我希望你喜欢它!
  • 但让我感到困惑的是 !!'false' 等于 true。就因为这种情况,我不能用这个技术。
  • !!'false' 确实是 true 因为'false' 是一个有效的字符串
  • 所以这个技术不能涵盖这种情况,或者有解决方法吗?
【解决方案7】:

我认为此答案需要更新,请查看旧答案的编辑历史记录。

基本上,您有三种不同的情况,即 null、undefined 和 undeclared,请参见下面的 sn-p。

// bad-file.ts
console.log(message)

你会得到一个错误,说变量 message 是未定义的(也就是未声明的),当然,Typescript 编译器不应该让你这样做,但真的没有什么可以阻止你。

// evil-file.ts
// @ts-gnore
console.log(message)

编译器很乐意只编译上面的代码。 因此,如果您确定所有变量都已声明,您可以简单地这样做

if ( message != null ) {
    // do something with the message
}

上面的代码将检查nullundefined,但是如果message变量可能未声明(为了安全),您可以考虑以下代码

if ( typeof(message) !== 'undefined' && message !== null ) {
    // message variable is more than safe to be used.
}

注意:typeof(message) !== 'undefined' && message !== null 此处的顺序非常重要,您必须先检查undefined 状态,否则它将与message != null 相同,谢谢@Jaider。

【讨论】:

  • M. Kamal 如果 something = 0,您使用 !something 的验证会给您带来问题。
  • @arturios 你能给我一个例子吗!!
  • @arturios 但是 0 在 JavaScript 中已经是一个假值了!!那么这里有什么意义呢?
  • @Al-un 不,在行动中看到它here
  • 更新版本错误。首先要检查的应该是未定义的......比如:if(typeof something !== 'undefined' && something !== null){...}
【解决方案8】:

对于Typescript 2.x.x,您应该按照以下方式进行操作(使用type guard):

tl;dr

function isDefined<T>(value: T | undefined | null): value is T {
  return <T>value !== undefined && <T>value !== null;
}

为什么?

这样isDefined() 将尊重变量的类型,并且以下代码将知道将此签入考虑在内。

示例 1 - 基本检查:

function getFoo(foo: string): void { 
  //
}

function getBar(bar: string| undefined) {   
  getFoo(bar); //ERROR: "bar" can be undefined
  if (isDefined(bar)) {
    getFoo(bar); // Ok now, typescript knows that "bar' is defined
  }
}

示例 2 - 尊重类型:

function getFoo(foo: string): void { 
  //
}

function getBar(bar: number | undefined) {
  getFoo(bar); // ERROR: "number | undefined" is not assignable to "string"
  if (isDefined(bar)) {
    getFoo(bar); // ERROR: "number" is not assignable to "string", but it's ok - we know it's number
  }
}

【讨论】:

  • 我希望他们将其添加为实用功能。
  • 请注意,对 nullish 的检查应该这样定义:function isNullish&lt;T&gt;(value: T | undefined | null): value is undefined | null { return &lt;T&gt;value === undefined || &lt;T&gt;value === null; }
  • @KfirDadosh 是对的,应该使用 isNullish 来代替,(或者如果你愿意,也可以称之为isNotDefined)。原代码的问题是如果类型参数T是null或者undefined,那么原代码会返回正确答案的反面。
【解决方案9】:
if(data){}

意思是!数据

  • 未定义
  • ....

【讨论】:

  • 如果数据是布尔类型?
  • 你可以结合两个变量,例如。 if(value1 && value2) 检查它们是否都未定义?
  • @ianstigator 布尔值只能计算为truefalse。如果您有一个带有null 分配或undefined 值的布尔值,则在这两种情况下,该值都将被评估为false
【解决方案10】:

更新(2020 年 9 月 4 日)

您现在可以使用?? 运算符来验证nullundefined“值”并设置默认值。例如:

const foo = null;
const bar = foo ?? 'exampleValue';
console.log(bar); // This will print 'exampleValue' due to the value condition of the foo constant, in this case, a null value

作为一种详细的方式,如果您想比较 nullundefinedONLY,请使用以下示例代码作为参考:

const incomingValue : string = undefined;
const somethingToCompare : string = incomingValue; // If the line above is not declared, TypeScript will return an excepion

if (somethingToCompare == (undefined || null)) {
  console.log(`Incoming value is: ${somethingToCompare}`);
}

如果incomingValue 没有被声明,TypeScript 应该返回一个异常。如果已声明但未定义,console.log() 将返回“传入值是:未定义”。请注意,我们没有使用严格的等于运算符。

“正确”方式(查看其他答案了解详情),如果incomingValue 不是boolean 类型,只需评估其值是否为真,这将根据常量/变量类型进行评估。 true 字符串必须使用= '' 分配明确定义为字符串。如果不是,它将被评估为false。让我们使用相同的上下文检查这个案例:

const incomingValue : string = undefined;
const somethingToCompare0 : string = 'Trumpet';
const somethingToCompare1 : string = incomingValue;

if (somethingToCompare0) {
  console.log(`somethingToCompare0 is: ${somethingToCompare0}`); // Will return "somethingToCompare0 is: Trumpet"
}

// Now, we will evaluate the second constant
if (somethingToCompare1) {
  console.log(`somethingToCompare1 is: ${somethingToCompare1}`); // Launched if incomingValue is defined
} else {
  console.log(`somethingToCompare1 is: ${somethingToCompare1}`); // Launched if incomingValue is undefined. Will return "somethingToCompare1 is: undefined"
}

【讨论】:

  • somethingToCompare == (未定义 || null)。 (undefined || null) 解析为 null,因此它是 somethingToCompare 和 null 之间的松散比较
  • @carlosvini 当然,比较的重点是冗长并提供代码供参考。这就是非严格等于比较的原因。答案的目的是明确和解释性的。我将编辑文本以避免混淆
  • 我不明白你的意思。代码不是冗长或明确的,充其量是令人困惑的,最坏的情况是完全错误的。代码a == (b || c)a == b || a == c相同,而是将评估b || c(在这种情况下为c,因为b 在您的示例中是虚假的)然后比较反对a
【解决方案11】:

如果您使用的是 TypeScript,那么让编译器检查空值和未定义(或其可能性)是一种更好的方法,而不是在运行时检查它们。 (如果您确实想在运行时检查,那么正如许多答案所示,只需使用value == null)。

使用编译选项strictNullChecks 告诉编译器阻塞可能的空值或未定义值。如果你设置了这个选项,然后出现你确实想要允许 null 和 undefined 的情况,你可以将类型定义为Type | null | undefined

【讨论】:

    【解决方案12】:

    如果你想在不将strict-boolean-expressions 设置为allow-null-unionallow-undefined-union 的情况下传递tslint,则需要使用nodeisNullOrUndefined 模块中的isNullOrUndefined 或自行滚动:

    // tslint:disable:no-null-keyword
    export const isNullOrUndefined =
      <T>(obj: T | null | undefined): obj is null | undefined => {
        return typeof obj === "undefined" || obj === null;
      };
    // tslint:enable:no-null-keyword
    

    不完全是语法糖,但当您的 tslint 规则很严格时很有用。

    【讨论】:

      【解决方案13】:

      简单的答案

      判断值是否为null,undefined,0,false,"",NaN

      if ( value )
      or
      if ( !!value )
      

      对于否定条件:

      if ( !value )
      

      仅测试nullundefined

      if ( value == null )
      

      更简洁的答案

      1- 如果值 不是,它将评估为 truenullundefinedNaN、@987654335 @、0false
      如果值为null,undefined,NaN,empty string,0,或false,将进入else条件。

      if ( value ) {
        console.log('value is something different from 0, "", false, NaN, null, undefined');
      } else {
        console.log('value is 0, "", false, NaN, null or undefined');
      }
      if ( !!value ) {
        console.log('value is something different from 0, "", false, NaN, null, undefined');
      } else {
        console.log('value is 0, "", false, NaN, null or undefined');
      }
      

      2-如果你想要一个否定条件,那么你需要使用:

      if ( !value ) {
        console.log('value is 0, "", false, NaN, null or undefined');
      } else {
        console.log('value is something different from 0, "", false, NaN, null, undefined');
      }
      

      3- 会判断值是null还是undefined

      if ( value == null ) {
        console.log('is null or undefined');
      } else {
        console.log('it isnt null neither undefined');
      }
      

      4- 使用布尔条件不起作用。
      如果值为 nullundefined0empty string、@ 987654353@
      这两个条件总是会转到 else 条件。
      如果 value 是布尔变量,则例外。

      if ( value==true ) {
      } else { 
      }
      if ( value==false ) {
      } else { 
      }
      

      【讨论】:

        【解决方案14】:

        最简单的方法是使用:

        import { isNullOrUndefined } from 'util';

        比:

        if (!isNullOrUndefined(foo))

        【讨论】:

        • 在这里效果很好
        • 来自函数文档:自 v4.0.0 起已弃用 - 请改用 value === null || value === undefined
        • @Aleksei 这很讽刺
        【解决方案15】:

        迟到加入这个线程,但我发现这个 JavaScript hack 在检查值是否未定义时非常方便

         if(typeof(something) === 'undefined'){
           // Yes this is undefined
         }
        

        【讨论】:

          【解决方案16】:

          可能为时已晚!但您可以在 typescript 中使用 ?? 运算符。 见https://mariusschulz.com/blog/nullish-coalescing-the-operator-in-typescript

          【讨论】:

            【解决方案17】:

            你可以使用

            if(x === undefined)
            

            【讨论】:

              【解决方案18】:

              全部,

              如果您使用的是对象,则得票最多的答案实际上并不适用。在这种情况下,如果属性不存在,则检查将不起作用。这就是我们案例中的问题:请参阅此示例:

              var x =
              { name: "Homer", LastName: "Simpson" };
              
              var y =
              { name: "Marge"} ;
              
              var z =
              { name: "Bart" , LastName: undefined} ;
              
              var a =
              { name: "Lisa" , LastName: ""} ;
              
              var hasLastNameX = x.LastName != null;
              var hasLastNameY = y.LastName != null;
              var hasLastNameZ = z.LastName != null;
              var hasLastNameA = a.LastName != null;
              
              
              
              alert (hasLastNameX + ' ' + hasLastNameY + ' ' + hasLastNameZ + ' ' + hasLastNameA);
              
              var hasLastNameXX = x.LastName !== null;
              var hasLastNameYY = y.LastName !== null;
              var hasLastNameZZ = z.LastName !== null;
              var hasLastNameAA = a.LastName !== null;
              
              alert (hasLastNameXX + ' ' + hasLastNameYY + ' ' + hasLastNameZZ + ' ' + hasLastNameAA);
              

              结果:

              true , false, false , true (in case of !=)
              true , true, true, true (in case of !==) => so in this sample not the correct answer
              

              plunkr 链接:https://plnkr.co/edit/BJpVHD95FhKlpHp1skUE

              【讨论】:

              【解决方案19】:

              null 检查的更快和更短的符号可以是:

              value == null ? "UNDEFINED" : value
              

              这一行相当于:

              if(value == null) {
                     console.log("UNDEFINED")
              } else {
                  console.log(value)
              }
              

              特别是当你有很多 null 时,检查它是一个很好的简短符号。

              【讨论】:

                【解决方案20】:

                我遇到了这个问题,其中一些答案对JS 很好,但对TS 却不行,这就是原因。

                //JS
                let couldBeNullOrUndefined;
                if(couldBeNullOrUndefined == null) {
                  console.log('null OR undefined', couldBeNullOrUndefined);
                } else {
                  console.log('Has some value', couldBeNullOrUndefined);
                }
                

                这一切都很好,因为 JS 没有类型

                //TS
                let couldBeNullOrUndefined?: string | null; // THIS NEEDS TO BE TYPED AS undefined || null || Type(string)
                
                if(couldBeNullOrUndefined === null) { // TS should always use strict-check
                  console.log('null OR undefined', couldBeNullOrUndefined);
                } else {
                  console.log('Has some value', couldBeNullOrUndefined);
                }
                

                如果变量没有用null 定义,则在TS 中,当您尝试检查null tslint |编译器会抱怨。

                //tslint.json
                ...
                "triple-equals":[true],
                ...
                
                 let couldBeNullOrUndefined?: string; // to fix it add | null
                
                 Types of property 'couldBeNullOrUndefined' are incompatible.
                      Type 'string | null' is not assignable to type 'string | undefined'.
                        Type 'null' is not assignable to type 'string | undefined'.
                

                【讨论】:

                  【解决方案21】:

                  通常我已经在discussed 中以 Fenton 的身份进行杂耍检查。 为了使其更具可读性,您可以使用 ramda 中的isNil

                  import * as isNil from 'ramda/src/isNil';
                  
                  totalAmount = isNil(totalAmount ) ? 0 : totalAmount ;
                  

                  【讨论】:

                    【解决方案22】:

                    小心,如果你使用本地存储,你可能会得到字符串 undefined 而不是 undefined 值:

                    localStorage.setItem('mykey',JSON.stringify(undefined));
                    localStorage.getItem('mykey') === "undefined"
                    true
                    

                    人们可能会觉得这很有用:https://github.com/angular/components/blob/master/src/cdk/coercion/boolean-property.spec.ts

                    /**
                     * @license
                     * Copyright Google LLC All Rights Reserved.
                     *
                     * Use of this source code is governed by an MIT-style license that can be
                     * found in the LICENSE file at https://angular.io/license
                     */
                    
                    /** Coerces a data-bound value (typically a string) to a boolean. */
                    export function coerceBooleanProperty(value: any): boolean {
                      return value != null && `${value}` !== 'false';
                    }
                    
                    import {coerceBooleanProperty} from './boolean-property';
                    
                    describe('coerceBooleanProperty', () => {
                    
                      it('should coerce undefined to false', () => {
                        expect(coerceBooleanProperty(undefined)).toBe(false);
                      });
                    
                      it('should coerce null to false', () => {
                        expect(coerceBooleanProperty(null)).toBe(false);
                      });
                    
                      it('should coerce the empty string to true', () => {
                        expect(coerceBooleanProperty('')).toBe(true);
                      });
                    
                      it('should coerce zero to true', () => {
                        expect(coerceBooleanProperty(0)).toBe(true);
                      });
                    
                      it('should coerce the string "false" to false', () => {
                        expect(coerceBooleanProperty('false')).toBe(false);
                      });
                    
                      it('should coerce the boolean false to false', () => {
                        expect(coerceBooleanProperty(false)).toBe(false);
                      });
                    
                      it('should coerce the boolean true to true', () => {
                        expect(coerceBooleanProperty(true)).toBe(true);
                      });
                    
                      it('should coerce the string "true" to true', () => {
                        expect(coerceBooleanProperty('true')).toBe(true);
                      });
                    
                      it('should coerce an arbitrary string to true', () => {
                        expect(coerceBooleanProperty('pink')).toBe(true);
                      });
                    
                      it('should coerce an object to true', () => {
                        expect(coerceBooleanProperty({})).toBe(true);
                      });
                    
                      it('should coerce an array to true', () => {
                        expect(coerceBooleanProperty([])).toBe(true);
                      });
                    });
                    

                    【讨论】:

                      【解决方案23】:

                      我们使用一个帮助器 hasValue 来检查空值/未定义并通过 TypeScript 确保不执行不必要的检查。 (后者类似于 TS 抱怨if ("a" === undefined) 的方式,因为它总是错误的)。

                      始终使用它总是安全的,不像!val 匹配空字符串、零等。它还避免使用模糊的== 匹配,这几乎总是一种不好的做法——不需要引入异常。

                      
                      
                      type NullPart<T> = T & (null | undefined);
                      
                      // Ensures unnecessary checks aren't performed - only a valid call if 
                      // value could be nullable *and* could be non-nullable
                      type MustBeAmbiguouslyNullable<T> = NullPart<T> extends never
                        ? never
                        : NonNullable<T> extends never
                        ? never
                        : T;
                      
                      export function hasValue<T>(
                        value: MustBeAmbiguouslyNullable<T>,
                      ): value is NonNullable<MustBeAmbiguouslyNullable<T>> {
                        return (value as unknown) !== undefined && (value as unknown) !== null;
                      }
                      
                      export function hasValueFn<T, A>(
                        value: MustBeAmbiguouslyNullable<T>,
                        thenFn: (value: NonNullable<T>) => A,
                      ): A | undefined {
                        // Undefined matches .? syntax result
                        return hasValue(value) ? thenFn(value) : undefined;
                      }
                      
                      
                      

                      【讨论】:

                        【解决方案24】:

                        因为 TypeScript 是 ES6 JavaScript 的类型化超集。 lodash 是一个 javascript 库。

                        使用 lodash 检查值是 null 还是 undefined 可以使用 _.isNil() 来完成。

                        _.isNil(value)
                        

                        参数

                        (*):要检查的值。

                        返回

                        (boolean):如果值为 null,则返回 true,否则返回 false。

                        示例

                        _.isNil(null);
                        // => true
                        
                        _.isNil(void 0);
                        // => true
                        
                        _.isNil(NaN);
                        // => false
                        

                        链接

                        Lodash Docs

                        【讨论】:

                        • 为什么这个方法是 -2 ? Lodash 不适合使用类型脚本?
                        【解决方案25】:

                        我总是这样写:

                        var foo:string;
                        
                        if(!foo){
                           foo="something";    
                        }
                        

                        这会很好,我认为它非常可读。

                        【讨论】:

                        • 不适用于数字,因为0 也通过了!foo 测试。
                        • 也不适用于布尔值,其中undefinedfalse 不同。这在可选布尔函数参数中很常见,您应该使用常见的 JavaScript 方法:function fn(flag?: boolean) { if (typeof flag === "undefined") flag = true; /* set default value */ }
                        • 对于布尔值似乎可以正常工作:var isTrue; if(isTrue)//skips, if(!isTrue)// enters if(isTrue === undefined)//enters。还使用未定义的var isTrue:boolean 在打字稿中进行了尝试,如果检查也相同。 @Gingi,你尝试的和我尝试的有什么不同吗?
                        猜你喜欢
                        • 1970-01-01
                        • 2020-01-10
                        • 1970-01-01
                        • 2020-09-18
                        • 2016-08-25
                        • 1970-01-01
                        • 2015-08-12
                        • 1970-01-01
                        相关资源
                        最近更新 更多