Hem "null" hem de "undefined" olup olmadığını kontrol etmenin bir yolu var mı?


382

TypeScript güçlü bir şekilde yazıldığından, yalnızca if () {}denetlemek için kullanın nullve undefineddoğru ses gelmiyor.

TypeScript'in bunun için özel bir işlevi veya sözdizimi şekeri var mı?


9
Since TypeScript is strongly-typedBunu bu dokümanlar bulamadım ve bu konuda şüphelerim var ...
pawciobiel

3
En son null olmayan türlerin okunmasını önerin, bu Dizgi 2'dir, ancak bugün itibariyle zaten beta sürümündedir. [Null edilemeyen türler # 7140] ( github.com/Microsoft/TypeScript/pull/7140 )
RyBolt

2
TypeScript'in hiçbir şey yapmak için özel işlevi yoktur. Bu bir yazım sistemi ve bir transpiler, bir kütüphane değil.

Yanıtlar:


378

Bir hokkabazlık-çek kullanarak, hem test edebilirsiniz nullve undefinedbir vuruşta:

if (x == null) {

Katı denetim kullanırsanız, bu yalnızca nulltanımlanmış değişkenler için doğru olur ve tanımlanmamış değişkenler için doğru olarak değerlendirilmez:

if (x === null) {

Bu örneği kullanarak bunu çeşitli değerlerle deneyebilirsiniz:

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

Çıktı

"a == null"

"a tanımsız"

"b == null"

"b === null"


52
"Hokkabazlık-kontrol" nedir?
kolobok

18
@akapelko, türün hokkabazlık yaptığı yerdir (yani "bu türü bir boole yapabilir miyiz"). Boş bir dize, örneğin, bir boole yanlışı olarak ele alınır. Hokkabazlık sırasında sık rastlanan bir hata: "false" == false"false" gibi boş olmayan bir dize olarak değerlendirilir true.
Fenton

12
Bunun nedeni JS'nin 'tip baskısı'.
Astravagrant

X'in 0 olması (ve bu geçerli bir değer) dışında, tanımsız / null testinizi geçecektir.
Jon Gunter

3
@JonGunter doğruluk / falsey if(x)tarzı kontroller için geçerli olurdu , ama değil if(x == null), sadece yakalar nullve undefined. Kullanarak var c: number = 0; check(c, 'b');"nully" null, veya olmadığını kontrol edin undefined.
Fenton

269
if( value ) {
}

için değerlendirecek trueeğer valuedeğildir:

  • null
  • undefined
  • NaN
  • boş dize ''
  • 0
  • false

daktilo javascript kurallarını içerir.


12
Değer boolean türündeyse ne olur?
ianstigator

iki değişkeni birleştirebilir misin örn. eğer her ikisinin de tanımsız olup olmadığını kontrol etmek için (değer1 && değer2)?
ARK

8
@ RamazanSağır evet teşekkürler biliyorum, ama gerçek şu ki 0 değeri sahip olabileceğim geçerli bir şey, yapmak istediğim tek kontrol değişkenin null veya undefined olmaması. Val! = Null (! == yerine! == yerine tanımsız değeri de denetler) kullanarak yapabileceğimi okudum
Alex

4
Tslint kuralı - "katı-boolean-ifadeleri" etkinse bu çözüm çalışmaz.
ip_x

1
Bize yanlışlık verirse yanlış, bu kadar basit değerlendirir.
Ayfri

50

TypeScript bunun için özel bir işleve veya sözdizimi şekerine sahip mi?

TypeScript, JavaScript sürümünü tam olarak anlar something == null.

Typescript doğru hem ekarte edecek nullve undefinedbu tür kontroller ile.

Daha

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


1
İki eşit yapmayı seviyorum myVar == null. Sadece başka bir seçenek.
David Sherret

30
== nullnull ve undefined için test etmenin doğru yoludur. !!somethingJS'de şartlı olarak işe yaramaz bir zorlamadır (sadece kullanın something). !!somethingayrıca 0 ve '' ifadelerini false değerine zorlar; bu, null / undefined arıyorsanız yapmak istediğiniz şey değildir.
C Snover

39

Daktilo oyun alanında farklı testler yaptım:

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

verir:

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

yani:

  • (a == null) 'ın null veya undefined olup olmadığını bilmek doğru olup olmadığını kontrol etme
  • a'nın tanımlanıp tanımlanmadığını (a! = null) doğru olup olmadığını kontrol etme
  • a'nın tanımlanıp tanımlanmadığını bilmek için (a) yanlış olup olmadığını kontrol etme

1
Bunun için neden TypeScript oyun alanını kullanasınız? Burada hiçbir şeyin TypeScript ile ilgisi yoktur.

10
Soru Dizgi ile ilgili olduğundan, Dizgi aktarıcısına karşı önerilen farklı çözümleri test etmeye çalışıyordum.
Juangui Jordán

6
TS transpiler bu kodun hiçbirini dönüştürmezdi.

31

Bu cevabın bir güncellemeye ihtiyacı olduğunu düşünüyorum, eski cevabın düzenleme geçmişini kontrol edin.

Temel olarak, boş, tanımsız ve bildirilmemiş üç farklı durumunuz var, aşağıdaki snippet'e bakın.

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

Bir hata alırsınız, değişken messagetanımsızdır (aka belirtilmemiş), elbette, Typcript derleyicisi bunu yapmanıza izin vermemelidir, ancak GERÇEKTEN hiçbir şey sizi engelleyemez.

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

Derleyici yukarıdaki kodu derlemekten mutluluk duyacaktır. Yani, tüm değişkenlerin bildirildiğinden eminseniz bunu yapabilirsiniz

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

Yukarıdaki kod kontrol eder nullve undefinedANCAK durumda messagedeğişken (güvenlik için) bildirilmeyen edilebilir, aşağıdaki kodu dikkate alabilir

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

Not: Buradaki sipariş typeof(message) !== 'undefined' && message !== nullçok önemlidir, önce undefineddurumu kontrol etmeniz gerekir, aksi takdirde message != nullteşekkürler @Jaider.


4
M. Kamal bir şey = 0 ise,! Bir şeyle doğrulamanız size sorun verecektir.
justcode

1
@arturios bana bir örnek verebilir misiniz !!
Ahmed Kamal

2
@arturios Ancak 0 zaten JavaScript'teki sahte bir değerdir !! Peki buradaki amaç nedir?
Ahmed Kamal

1
@ Al-un hayır, burada
Ahmed Kamal

1
güncellenen sürüm yanlış. Kontrol edilecek ilk şey tanımsız olmalı ... gibi:if(typeof something !== 'undefined' && something !== null){...}
Jaider

27

In typescript 3.7 şu anda elimizde Opsiyonel zincirleme ve Nullish kaynaştırma kontrol etmek null adlı ve tanımsız aynı sürede, örnek:

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

bu kod foo'nun tanımlanıp tanımlanmadığını kontrol eder, aksi takdirde tanımsız olarak döner

eski yol :

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

bu:

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

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

İsteğe bağlı zincirleme ile:

let x = foo?.bar();

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

diğer bir yeni özellik de Nullish Coalescing , örnek:

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

eski yol:

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

3
Bu şimdi kabul edilen cevap olmalı. Typcript 3.7 ayrıca "Nullish Coalescing" i de destekliyor. var foo = possibleUndefinedOrNull ?? fallbackValueIfFirstValueIsUndefinedOrNull; İşte belgeler: typescriptlang.org/docs/handbook/release-notes/…
tkd_aj

23

Denemek isteyebilirsiniz

if(!!someValue)

ile !!.

açıklama

Birincisi !ifadenizi bir booleandeğere dönüştürecektir .

Sonra !someValueise trueeğer someValueolduğunu falsy ve falseeğer someValueolduğunu truthy . Bu kafa karıştırıcı olabilir.

Başka ekleyerek !, ifade şimdi trueise someValueise truthy ve falseeğer someValueolduğunu falsy yönetmek çok daha kolay olan.

Tartışma

Şimdi, neden if (!!someValue)benzer bir şey if (someValue)bana aynı sonucu verirse kendimi neden rahatsız ediyorum ?

Çünkü !!someValuekesinlikle boolean bir ifadedir, oysa someValuekesinlikle her şey olabilir. Bu tür bir ifade şimdi fonksiyonlar (ve Tanrı'ya ihtiyacımız var) yazmak gibi olacak:

isSomeValueDefined(): boolean {
  return !!someValue
}

onun yerine:

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

Umut ediyorum bu yardım eder.


öyleyse, someValue 'false' (dize türünde) ise, !! someValue false (boolean tipinde)?
paul cheung

Sanırım böyle diyebilirsin.Bu teknik tam da bu tür karışıklıklardan kaçınmak için kullanılıyor. Umarım beğenmişsindir!
avi.elkharrat

ama beni şaşırtan şey 'yanlış' doğru. Sadece bu dava yüzünden bu tekniği kullanamıyorum.
paul cheung

!!'false'senet olduğu trueiçin 'false'geçerli bir dize
avi.elkharrat

yani bu teknik bu durumu kapatamaz mı, yoksa geçici bir çözüm var mı?
paul cheung

16

Çünkü Typescript 2.x.xbunu aşağıdaki şekilde yapmalısınız ( tip koruyucuyu kullanarak ):

tl; Dr.

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

Neden?

Bu şekilde isDefined()değişkenin türüne saygı duyulur ve aşağıdaki kod bu kontrolü dikkate alır.

Örnek 1 - temel kontrol:

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
  }
}

Örnek 2 - Türlere saygı:

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
  }
}

14
if(data){}

bu demek oluyor ki

  • boş
  • Tanımsız
  • yanlış
  • ....

2
Ve eğer veriler boole tipindeyse?
ianstigator

iki değişkeni birleştirebilir misin örn. eğer her ikisinin de tanımsız olup olmadığını kontrol etmek için (değer1 && değer2)?
ARK

@ianstigator Bir boole sadece trueveya falsesadece olarak değerlendirilebilir . nullAtama veya undefineddeğer içeren bir booleanız varsa , her iki durumda da değer olarak değerlendirilir false.
KBeDev

5

TypeScript kullanıyorsanız, derleyicinin çalışma zamanında denetlemek yerine null'ları ve tanımsızları (veya olasılığını) denetlemesine izin vermek daha iyi bir yaklaşımdır. (Çalışma zamanında kontrol etmek istiyorsanız, cevapların belirttiği gibi, sadece kullanın value == null).

strictNullChecksDerleyiciye olası boş veya tanımsız değerleri boğmasını bildirmek için derleme seçeneğini kullanın . Bu seçeneği ayarlamak ve sonra bir durum varsa do null adlı izin ve tanımsız istiyoruz, siz türünü tanımlayabilirsiniz Type | null | undefined.


5

Eğer geçmek istiyorsanız tslintayarlamadan strict-boolean-expressionsiçin allow-null-unionya allow-undefined-union, sen kullanımına ihtiyaç isNullOrUndefinedden nodes' utilmodülü veya kendi rulo:

// 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

Tam sözdizimsel şeker değil, tslint kurallarınız sıkı olduğunda yararlıdır.


1

nullKontroller için daha hızlı ve daha kısa bir gösterim olabilir:

value == null ? "UNDEFINED" : value

Bu satır şuna eşdeğerdir:

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

Özellikle çok fazla nullçekiniz olduğunda hoş bir kısa gösterimdir.


1

Ben bu sorunu vardı ve bazı cevap işe yarıyor JSama TSburada değil nedeni.

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

JS'nin Türleri olmadığı için hepsi iyi

//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);
}

TS değişken ile tanımlı olmasaydı nullbunun için kontrol çalıştığınızda | derleyici şikayet edecek.nulltslint

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

1

Bu konuya geçmek için geç kaldım, ancak bu JavaScript hackinin bir değerin tanımlanıp tanımlanmadığını kontrol etmede çok kullanışlı olduğunu düşünüyorum

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

1

Genellikle Fenton'un zaten tartıştığı gibi hokkabazlık kontrolünü yaparım . Daha okunabilir hale getirmek için, ramda'dan isNil'i kullanabilirsiniz .

import * as isNil from 'ramda/src/isNil';

totalAmount = isNil(totalAmount ) ? 0 : totalAmount ;

1

Ayrıntılı bir yol olarak, SADECE boş ve tanımsız değerleri karşılaştırmak istiyorsanız , referans için aşağıdaki örnek kodu kullanın:

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}`);
}

Eğer incomingValuebildirilmedi, typescript bir istisna dönmelidir. Bu beyan edilmiş ancak tanımlanmamışsa,console.log() "Gelen değer: tanımsız" değerini döndürür. Sıkı eşit işleç kullanmadığımızı unutmayın.

"Doğru" yol (ayrıntılar için diğer yanıtları kontrol edin), eğer incomingValuebir booleantür değilse , sadece değerinin doğru olup olmadığını değerlendirin, bu sabit / değişken tipine göre değerlendirilecektir. Bir truedize, = ''atama kullanılarak açıkça dize olarak tanımlanmalıdır . Değilse, olarak değerlendirilecektir false. Aynı durumu kullanarak bu durumu kontrol edelim:

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 == (tanımsız || null). (undefined || null) null
değerine gider

@carlosvini Elbette, karşılaştırmanın amacı ayrıntılı olmak ve referans için bir kod sağlamaktır. Bu katı olmayan eşit karşılaştırmanın sebebidir. Cevabın amacı açık ve açıklayıcı olmaktır. Karışıklığı önlemek için metni düzenleyeceğim
KBeDev


0

Herşey,

En çok oy alan cevap, bir nesne ile çalışıyorsanız gerçekten işe yaramaz. Bu durumda, bir özellik yoksa, denetim çalışmaz. Bizim durumumuzdaki sorun buydu: şu örneğe bakın:

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

Sonuç:

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

plunkr bağlantısı: https://plnkr.co/edit/BJpVHD95FhKlpHp1skUE


Bu iyi bir test değil. Bu değerlerin hiçbiri kesinlikle değildir null . Bunu deneyin: plnkr.co/edit/NfiVnQNes1p8PvXd1fCG?p=preview
simonhamp

0

TypeScript, ES6 JavaScript'in yazılı üst kümesi olduğundan. Ve kahkaha bir javascript kütüphanesi.

Değer null veya undefined olup olmadığını kontrol etmek için lodash kullanımı kullanılarak yapılabilir _.isNil().

_.isNil(value)

Argümanlar

değer (*): Kontrol edilecek değer.

İadeler

(boolean) : Değer nullish ise true değerini, aksi takdirde false değerini döndürür.

Misal

_.isNil(null);
// => true

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

_.isNil(NaN);
// => false

bağlantı

Lodash Dokümanları


1
Bu yöntem neden -2'dir? Lodash, script ile iyi değil mi?
Thomas Poignant

0

Yerel depolama alanı kullanıyorsanız dikkatli olun, tanımsız değer yerine tanımsız dizeyle sonuçlanabilir:

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

İnsanlar bunu faydalı bulabilir: 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);
  });
});

-4

Her zaman böyle yazıyorum:

var foo:string;

if(!foo){
   foo="something";    
}

Bu iyi çalışır ve bence çok okunabilir.


21
Testi 0geçtiği için sayılar için çalışmaz !foo.
17'de

10
Boolean için de çalışmaz, burada undefinedfarklıdır false. Bu, ortak JavaScript yaklaşımını kullanmanız gereken isteğe bağlı boole işlev parametreleriyle çok yaygındır:function fn(flag?: boolean) { if (typeof flag === "undefined") flag = true; /* set default value */ }
Gingi

Boolelerde için çalışma OK görünüyor: var isTrue; if(isTrue)//skips, if(!isTrue)// enters if(isTrue === undefined)//enters. Ayrıca var isTrue:booleantanımsız olan daktiloda denedi ve eğer kontrol ederse aynı. @Gingi, denedikleriniz ve denediklerim hakkında farklı bir şey var mı?
Drenai
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.