Gibt es eine Möglichkeit, nach "null" und "undefiniert" zu suchen?


382

Da TypeScript stark typisiert ist, wird einfach if () {}nach gesucht nullund es undefinedklingt nicht richtig.

Hat TypeScript dafür eine spezielle Funktion oder Syntax?


9
Since TypeScript is strongly-typedIch konnte dies nicht in den Dokumenten finden und ich habe Zweifel daran ...
Pawciobiel

3
Es wird empfohlen, sich über die neuesten nicht nullbaren Typen zu informieren. Dies ist Typescript 2, befindet sich jedoch bereits heute in der Beta. [Nicht nullfähige Typen # 7140] ( github.com/Microsoft/TypeScript/pull/7140 )
RyBolt

2
TypeScript hat keine dedizierten Funktionen, um etwas zu tun. Es ist ein Schreibsystem und ein Transpiler, keine Bibliothek.

Antworten:


378

Mit einem Jonglier-Check können Sie beide nullund undefinedmit einem Schlag testen :

if (x == null) {

Wenn Sie eine strenge Prüfung verwenden, gilt diese nur für Werte, die auf nullundefinierte Variablen festgelegt sind, und wird nicht als wahr ausgewertet:

if (x === null) {

Sie können dies mit verschiedenen Werten anhand dieses Beispiels versuchen:

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

Ausgabe

"a == null"

"a ist undefiniert"

"b == null"

"b === null"


52
Was ist "Jonglier-Check"?
Kolobok

18
@akapelko ist es, wo der Typ jongliert wird (dh "können wir diesen Typ zu einem Booleschen machen"). So wird beispielsweise eine leere Zeichenfolge als boolescher Wert false behandelt. Ein häufiger Fehler beim Jonglieren ist: "false" == falseEine nicht leere Zeichenfolge wie "false" wird ausgewertet true.
Fenton

12
Dies ist auf JS '' Typenzwang 'zurückzuführen.
Astravagrant

Außer wenn x 0 ist (und das ist ein gültiger Wert), besteht es Ihren undefinierten / Null-Test.
Jon Gunter

3
@ JonGunter, das wäre wahr für Wahrheits- / False- if(x)Style-Checks, aber nicht if(x == null), was nur fängt nullund undefined. Überprüfen Sie, var c: number = 0; check(c, 'b');ob es nicht "nully" ist null, oder undefined.
Fenton

269
if( value ) {
}

wird bewerten, truewenn valuenicht:

  • null
  • undefined
  • NaN
  • leerer String ''
  • 0
  • false

Typoskript enthält Javascript-Regeln.


12
Was ist, wenn der Wert vom booleschen Typ ist?
Ianstigator

können Sie zwei Variablen kombinieren, z. if (Wert1 && Wert2), um zu überprüfen, ob beide undefiniert sind?
ARK

8
@ RamazanSağır Ja, danke, das weiß ich, aber der Wert 0 ist etwas Gültiges, das ich haben kann. Die einzige Überprüfung, die ich durchführen möchte, ist, dass die Variable weder null noch undefiniert ist. Ich habe gelesen, dass ich es tun kann, indem ich val! = Null benutze (das! = Anstelle von! == prüft auch undefinierten Wert)
Alex

4
Diese Lösung funktioniert nicht, wenn die tslint-Regel "strict-boolean-expression" aktiviert ist.
IP_x

1
Es wird falsch bewertet, wenn der Wert uns falsch ist, so einfach wie dieser.
Ayfri

50

Hat TypeScript dafür eine spezielle Funktion oder Syntax?

TypeScript versteht die JavaScript-Version vollständig something == null .

TypeScript schließt sowohl nullund als auch korrekt ausundefined solche Überprüfungen .

Mehr

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


1
Ich mache gerne zwei Gleiche myVar == null. Nur eine weitere Option.
David Sherret

30
== nullist der richtige Weg, um auf null und undefiniert zu testen. !!somethingist ein nutzloser Zwang in einer Bedingung in JS (nur verwenden something). !!somethingzwingt auch 0 und '' zu false, was Sie nicht tun möchten, wenn Sie nach null / undefined suchen.
C Snover

39

Ich habe verschiedene Tests auf dem Typoskript-Spielplatz durchgeführt:

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

gibt:

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

damit:

  • Überprüfen Sie, ob (a == null) richtig ist, um festzustellen, ob a null oder undefiniert ist
  • Überprüfen, ob (a! = null) richtig ist, um zu wissen, ob a definiert ist
  • Überprüfen, ob (a) falsch ist, um zu wissen, ob a definiert ist

1
Warum sollten Sie dafür den TypeScript-Spielplatz verwenden? Hier hat nichts mit TypeScript zu tun.

10
Da sich die Frage auf Typescript bezog, habe ich versucht, verschiedene vorgeschlagene Lösungen gegen den Typescript-Transpiler zu testen.
Juangui Jordán

6
Der TS-Transpiler würde diesen Code überhaupt nicht transformieren.

31

Ich denke, diese Antwort muss aktualisiert werden. Überprüfen Sie den Bearbeitungsverlauf auf die alte Antwort.

Grundsätzlich haben Sie drei aufgeschobene Fälle null, undefiniert und nicht deklariert (siehe den folgenden Ausschnitt).

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

Sie erhalten eine Fehlermeldung, dass die Variable messageundefiniert (auch als nicht deklariert bezeichnet) ist. Der Typescript-Compiler sollte dies natürlich nicht zulassen, aber WIRKLICH kann Sie nichts davon abhalten.

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

Der Compiler kompiliert gerne den obigen Code. Wenn Sie also sicher sind, dass alle Variablen deklariert sind, können Sie dies einfach tun

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

Der obige Code prüft auf nullund undefined, ABER falls die messageVariable (aus Sicherheitsgründen) nicht deklariert ist, können Sie den folgenden Code berücksichtigen

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

Hinweis: Die Reihenfolge hier typeof(message) !== 'undefined' && message !== nullist sehr wichtig. Sie müssen undefinedzuerst den Status überprüfen, da er genau so ist wie message != null, danke @Jaider.


4
M. Kamal, wenn etwas = 0 ist, wird Ihre Überprüfung mit! Etwas Ihnen Probleme bereiten.
Justcode

1
@arturios kannst du mir bitte ein beispiel geben !!
Ahmed Kamal

2
@arturios Aber 0 ist schon ein falscher Wert in JavaScript !! Worum geht es hier?
Ahmed Kamal

1
@ Al-un nein, sehen Sie es in Aktion hier
Ahmed Kamal

1
Die aktualisierte Version ist falsch. Das erste, was zu überprüfen ist, sollte undefiniert sein ... wie:if(typeof something !== 'undefined' && something !== null){...}
Jaider

27

In TypeScript 3.7 haben wir jetzt optionales Verketten und Nullish Coalescing , um gleichzeitig null und undefiniert zu prüfen. Beispiel:

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

Dieser Code prüft, ob foo definiert ist, andernfalls wird undefiniert zurückgegeben

alter Weg :

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

diese:

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

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

Mit optionaler Verkettung wird:

let x = foo?.bar();

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

Eine weitere neue Funktion ist Nullish Coalescing , Beispiel:

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

Alter Weg:

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

3
Dies sollte jetzt die akzeptierte Antwort sein. Typescript 3.7 unterstützt auch "Nullish Coalescing". var foo = möglichUndefinedOrNull ?? fallbackValueIfFirstValueIsUndefinedOrNull; Hier ist die Dokumentation: typescriptlang.org/docs/handbook/release-notes/...
tkd_aj

23

Vielleicht möchten Sie es versuchen

if(!!someValue)

mit !!.

Erläuterung

Der erste !verwandelt Ihren Ausdruck in einen booleanWert.

Dann !someValueist, trueob someValuees falsch ist und falseob someValuees wahr ist . Dies könnte verwirrend sein.

Durch Hinzufügen eines weiteren !, jetzt ist der Ausdruck , truewenn someValueist truthy und falsewenn someValueist falsy , die viel einfacher zu verwalten ist.

Diskussion

Warum beschäftige ich mich jetzt mit so if (!!someValue)etwas?if (someValue) mir das gleiche Ergebnis gebracht hätte?

Denn !!someValueist genau ein boolescher Ausdruck, während someValueabsolut alles sein könnte. Diese Art des Ausdrucks ermöglicht es nun, Funktionen (und Gott, die wir brauchen) wie folgt zu schreiben:

isSomeValueDefined(): boolean {
  return !!someValue
}

anstatt:

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

Ich hoffe, es hilft.


Also, wenn someValue 'false' ist (mit String-Typ), dann !! someValue ist false (boolescher Typ)?
Paul Cheung

Ich denke, Sie können es sagen. Diese Technik wird genau verwendet, um diese Art von Verwirrung zu vermeiden. Ich hoffe du magst es!
Avi.elkharrat

aber was mich verwirrt hat ist !! 'falsch' ist gleich wahr. Nur wegen dieses Falles kann ich diese Technik nicht verwenden.
Paul Cheung

!!'false'ist in der Tat, trueweil 'false'es eine gültige Zeichenfolge ist
avi.elkharrat

Diese Technik kann diesen Fall also nicht abdecken, oder gibt es eine Problemumgehungslösung?
Paul Cheung

16

Denn Typescript 2.x.xSie sollten es folgendermaßen tun (mit Type Guard ):

tl; dr

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

Warum?

Auf diese Weise isDefined()wird der Variablentyp berücksichtigt und der folgende Code würde wissen, dass diese Prüfung berücksichtigt wird.

Beispiel 1 - Grundprüfung:

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

Beispiel 2 - Typen respektieren:

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

Es ist gemein! Daten

  • Null
  • nicht definiert
  • falsch
  • ....

2
Und wenn Daten vom booleschen Typ sind?
Ianstigator

können Sie zwei Variablen kombinieren, z. if (Wert1 && Wert2), um zu überprüfen, ob beide undefiniert sind?
ARK

@ianstigator Ein Boolescher Wert kann als trueoder falsenur ausgewertet werden . Wenn Sie einen Booleschen Wert mit einer nullZuweisung oder einem undefinedWert haben, wird der Wert in beiden Fällen als ausgewertet false.
KBeDev

5

Wenn Sie TypeScript verwenden, ist es besser, den Compiler nach Nullen und Undefinierten (oder deren Möglichkeit) suchen zu lassen, als zur Laufzeit nach ihnen zu suchen. (Wenn Sie zur Laufzeit überprüfen möchten, verwenden Sie einfach, wie viele Antworten anzeigen value == null.)

Verwenden Sie die Kompilierungsoption strictNullChecks, um den Compiler anzuweisen, mögliche Null- oder undefinierte Werte zu drosseln. Wenn Sie diese Option gesetzt, und dann gibt es eine Situation , wo Sie es möchten null ermöglichen und nicht definiert, können Sie die Art , wie definieren Type | null | undefined.


5

Wenn Sie übergeben möchten , tslintohne Einstellung strict-boolean-expressionszu allow-null-unionoder allow-undefined-unionmüssen Sie die Verwendung isNullOrUndefinedvon node‚s - utilModul oder rollen Sie Ihre eigenen:

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

Nicht gerade syntaktischer Zucker, aber nützlich, wenn Ihre tslint-Regeln streng sind.


1

Eine schnellere und kürzere Notation für nullSchecks kann sein:

value == null ? "UNDEFINED" : value

Diese Zeile entspricht:

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

Besonders wenn Sie viel nullScheck haben, ist es eine schöne kurze Notation.


1

Ich hatte dieses Problem und einige der Antworten funktionieren gut, JSaber nicht für TShier ist der Grund.

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

Das ist alles gut, da JS keine Typen hat

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

In TS , wenn die Variable nicht definiert wurde , mit , nullwenn Sie versuchen, das zu überprüfen , nulldie tslint| Compiler wird sich beschweren.

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

Spät, um diesem Thread beizutreten, aber ich finde diesen JavaScript-Hack sehr praktisch, um zu überprüfen, ob ein Wert undefiniert ist

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

1

Normalerweise mache ich den Jonglier-Check, wie Fenton bereits besprochen hat . Um die Lesbarkeit zu verbessern , können Sie isNil von ramda verwenden.

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

totalAmount = isNil(totalAmount ) ? 0 : totalAmount ;

1

Wenn Sie NUR null und undefinierte Werte vergleichen möchten , verwenden Sie den ausführlichen Beispielcode als Referenz:

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

Wenn dies incomingValuenicht deklariert ist, sollte TypeScript eine Ausnahme zurückgeben. Wenn dies deklariert, aber nicht definiert ist, wird dieconsole.log() wird "Eingehender Wert ist: undefiniert" zurückgegeben. Beachten Sie, dass wir nicht den strengen Gleichheitsoperator verwenden.

Der "richtige" Weg (überprüfen Sie die anderen Antworten auf Details), wenn der incomingValuekein booleanTyp ist, bewerten Sie einfach, ob sein Wert wahr ist, dies wird gemäß dem Typ der Konstanten / Variablen ausgewertet. Eine trueZeichenfolge muss mithilfe der = ''Zuweisung explizit als Zeichenfolge definiert werden . Wenn nicht, wird es als bewertet false. Lassen Sie uns diesen Fall im selben Kontext überprüfen:

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 == (undefiniert || null). (undefined || null) wird in null aufgelöst, daher ist es ein loser Vergleich zwischen
SomethingToCompare

@carlosvini Sicher, der Punkt des Vergleichs ist es, ausführlich zu sein und einen Code als Referenz bereitzustellen. Das ist der Grund für den nicht strengen Gleichheitsvergleich. Der Zweck der Antwort ist klar und erklärend. Ich werde den Text bearbeiten, um Verwirrung zu vermeiden
KBeDev


0

Alle,

Die Antwort mit den meisten Stimmen funktioniert nicht wirklich, wenn Sie mit einem Objekt arbeiten. In diesem Fall funktioniert die Prüfung nicht, wenn eine Eigenschaft nicht vorhanden ist. Und das war das Problem in unserem Fall: siehe dieses Beispiel:

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

Ergebnis:

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

plunkr link: https://plnkr.co/edit/BJpVHD95FhKlpHp1skUE


Dies ist kein guter Test. Keiner dieser Werte ist streng null . Versuchen Sie Folgendes
simonhamp

0

Da TypeScript eine typisierte Obermenge von ES6-JavaScript ist. Und lodash sind eine Bibliothek von Javascript.

Mit lodash können Sie überprüfen, ob der Wert null oder undefiniert ist _.isNil().

_.isNil(value)

Argumente

Wert (*): Der zu überprüfende Wert.

Kehrt zurück

(boolean) : Gibt true zurück, wenn der Wert nullish ist, andernfalls false.

Beispiel

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

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

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

Verknüpfung

Lodash Docs


1
Warum sind diese Methoden -2? Lodash ist nicht gut mit Typenskript?
Thomas Poignant

0

Vorsicht, wenn Sie lokalen Speicher verwenden, kann die Zeichenfolge undefiniert und nicht der Wert undefiniert sein:

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

Personen finden dies möglicherweise hilfreich: 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

Ich schreibe es immer so:

var foo:string;

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

Dies wird gut funktionieren und ich denke, es ist sehr gut lesbar.


21
Würde nicht für Zahlen funktionieren, da 0auch der !fooTest bestanden wird.
hasen

10
Funktioniert auch nicht für Boolesche Werte, bei denen undefinedes sich von unterscheidet false. Dies ist sehr häufig bei optionalen booleschen Funktionsparametern, bei denen Sie den allgemeinen JavaScript-Ansatz verwenden sollten:function fn(flag?: boolean) { if (typeof flag === "undefined") flag = true; /* set default value */ }
Gingi

Scheint für Boolesche in Ordnung zu sein : var isTrue; if(isTrue)//skips, if(!isTrue)// enters if(isTrue === undefined)//enters. Versuchte es auch in Typoskript, mit var isTrue:booleandem undefiniert war, und das gleiche, wenn prüft. @Gingi, gibt es etwas anderes an dem, was du versucht hast und was ich versucht habe?
Drenai
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.