Có cách nào để kiểm tra cả `null` và` không xác định` không?


382

Vì TypeScript được gõ mạnh, chỉ cần sử dụng if () {}để kiểm tra nullundefinednghe không đúng.

TypeScript có bất kỳ chức năng chuyên dụng hoặc cú pháp đường cho việc này không?


9
Since TypeScript is strongly-typedTôi không thể tìm thấy điều này trong các tài liệu và tôi nghi ngờ về điều đó ...
pawciobiel

3
Đề nghị đọc lên các loại không thể mới nhất, đây là Kiểu 2, nhưng đã ở giai đoạn thử nghiệm cho đến ngày hôm nay. [Các loại không nullable # 7140] ( github.com/Microsoft/TypeScript/pull/7140 )
RyBolt

2
TypeScript không có chức năng chuyên dụng để làm bất cứ điều gì. Đó là một hệ thống đánh máy và bộ chuyển mã, không phải thư viện.

Câu trả lời:


378

Sử dụng kiểm tra tung hứng, bạn có thể kiểm tra cả hai nullundefinedtrong một lần nhấn:

if (x == null) {

Nếu bạn sử dụng kiểm tra nghiêm ngặt, nó sẽ chỉ đúng với các giá trị được đặt thành nullvà sẽ không đánh giá là đúng với các biến không xác định:

if (x === null) {

Bạn có thể thử điều này với các giá trị khác nhau bằng cách sử dụng ví dụ này:

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

Đầu ra

"a == null"

"a là không xác định"

"b == null"

"b === null"


52
"Kiểm tra tung hứng" là gì?
kolobok

18
@akapelko đó là nơi loại được tung hứng (nghĩa là "chúng ta có thể biến loại này thành boolean"). Vì vậy, một chuỗi rỗng được coi là sai boolean, ví dụ. Một lỗi phổ biến khi tung hứng là: "false" == falsemột chuỗi không trống như "false" ước tính true.
Fenton

12
Điều này là do 'kiểu ép buộc' của JS.
Astravagrant

Ngoại trừ nếu x bằng 0 (và đó là giá trị hợp lệ), nó sẽ vượt qua bài kiểm tra không xác định / null của bạn.
Jon Gunter

3
@JonGunter sẽ đúng với if(x)kiểm tra kiểu trung thực / falsey , nhưng không if(x == null), chỉ bắt nullundefined. Kiểm tra nó bằng cách sử dụng var c: number = 0; check(c, 'b');nó không "nully" null, hoặc undefined.
Fenton

269
if( value ) {
}

sẽ đánh giá truenếu valuekhông:

  • null
  • undefined
  • NaN
  • chuỗi rỗng ''
  • 0
  • false

bản thảo bao gồm các quy tắc javascript.


12
Nếu giá trị thuộc loại boolean thì sao?
ianstigator

bạn có thể kết hợp hai biến, ví dụ. if (value1 && value2) để kiểm tra xem cả hai đều không xác định?
ARK

8
@ RamazanSağır vâng cảm ơn tôi biết điều đó, nhưng thực tế là giá trị 0 là thứ hợp lệ mà tôi có thể có, kiểm tra duy nhất tôi muốn làm là biến đó không phải là null hoặc không xác định. Tôi đã đọc rằng tôi có thể làm điều đó bằng cách sử dụng val! = Null (the! = Thay vì! == cũng kiểm tra giá trị không xác định)
Alex

4
Giải pháp này sẽ không hoạt động nếu quy tắc tslint - "biểu thức nghiêm ngặt-boolean" được bật.
ip_x

1
Nó sẽ đánh giá sai nếu giá trị chúng tôi giả, đơn giản như thế này.
Ayfri

50

TypeScript có chức năng chuyên dụng hoặc cú pháp đường cho việc này không

TypeScript hoàn toàn hiểu phiên bản JavaScript something == null.

TypeScript sẽ loại trừ chính xác cả hai nullundefinedvới các kiểm tra như vậy.

Hơn

https://basarat.gitbook.io/typescript/recap/null-und xác định


1
Tôi thích làm hai bằng nhau myVar == null. Chỉ là một lựa chọn khác.
David Sherret 11/03/2015

30
== nulllà cách chính xác để kiểm tra null & không xác định. !!somethinglà một sự ép buộc vô ích trong một điều kiện trong JS (chỉ sử dụng something). !!somethingcũng sẽ ép buộc 0 và '' thành false, đó không phải là điều bạn muốn làm nếu bạn đang tìm kiếm null / không xác định.
C Snover 11/03/2015

39

Tôi đã làm các bài kiểm tra khác nhau trên sân chơi bản thảo:

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

cho:

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

vì thế:

  • kiểm tra xem (a == null) có đúng không khi biết a là null hoặc không xác định
  • kiểm tra xem (a! = null) có đúng không nếu biết a được xác định
  • kiểm tra nếu (a) sai để biết nếu a được xác định

1
Tại sao bạn lại sử dụng sân chơi TypeScript cho việc này? Không có gì ở đây có liên quan đến TypeScript.

10
Bởi vì câu hỏi có liên quan đến Bản mô tả, tôi đã cố gắng kiểm tra các giải pháp được đề xuất khác nhau đối với trình chuyển mã Bản sao.
Juangui Jordán

6
Bộ chuyển mã TS sẽ không chuyển đổi bất kỳ mã nào cả.

31

Tôi nghĩ rằng câu trả lời này cần một bản cập nhật, kiểm tra lịch sử chỉnh sửa cho câu trả lời cũ.

Về cơ bản, bạn có ba trường hợp trì hoãn null, không xác định và không khai báo, xem đoạn trích dưới đây.

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

Bạn sẽ gặp một lỗi nói rằng biến đó messagekhông được xác định (còn gọi là không khai báo), tất nhiên, trình biên dịch Typecript không nên cho phép bạn làm điều đó nhưng THỰC SỰ không có gì có thể ngăn cản bạn.

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

Trình biên dịch sẽ rất vui khi chỉ biên dịch mã ở trên. Vì vậy, nếu bạn chắc chắn rằng tất cả các biến được khai báo, bạn chỉ cần làm điều đó

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

mã ở trên sẽ kiểm tra nullundefined, NHƯNG trong trường hợp messagebiến có thể không được khai báo (để đảm bảo an toàn), bạn có thể xem xét mã sau

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

Lưu ý: thứ tự ở đây typeof(message) !== 'undefined' && message !== nullrất quan trọng bạn phải kiểm tra undefinedtrạng thái trước tiên, nó sẽ giống như message != null, cảm ơn @Jaider.


4
M. Kamal nếu cái gì đó = 0, xác minh của bạn với! Một cái gì đó sẽ cung cấp cho bạn vấn đề.
mã hóa

1
@arturios bạn có thể vui lòng cho tôi một ví dụ !!
Ahmed Kamal

2
@arturios Nhưng 0 đã là một giá trị giả trong JavaScript !! Vì vậy, điểm ở đây là gì?
Ahmed Kamal

1
@ Al-un không, xem nó hoạt động ở đây
Ahmed Kamal

1
phiên bản cập nhật là sai. Điều đầu tiên cần kiểm tra không được xác định ... như:if(typeof something !== 'undefined' && something !== null){...}
Jaider

27

Trong TypeScript 3.7, giờ đây chúng ta có Chuỗi kết hợpNullish Coalescing tùy chọn để kiểm tra nullkhông xác định cùng một lúc, ví dụ:

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

mã này sẽ kiểm tra nếu foo được xác định nếu không nó sẽ trả về không xác định

cách cũ :

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

điều này:

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

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

Với chuỗi tùy chọn sẽ là:

let x = foo?.bar();

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

một tính năng mới khác là Nullish Coalescing , ví dụ:

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

cách cũ:

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

3
Đây phải là câu trả lời được chấp nhận ngay bây giờ. Bản đánh máy 3.7 cũng hỗ trợ "Nullish Coalescing". var foo = ossibleUnd xác địnhNull ?? fallbackValue IfFirstValueIsUnd xác địnhNull; Dưới đây là tài liệu: typescriptlang.org/docs/handbook/release-notes/...
tkd_aj

23

Bạn có thể muốn thử

if(!!someValue)

với !!.

Giải trình

Đầu tiên !sẽ biến biểu thức của bạn thành một booleangiá trị.

Sau đó !someValuetruenếu someValuefalsyfalsenếu someValuetruthy . Điều này có thể gây nhầm lẫn.

Bằng cách thêm khác !, khái niệm tại là truenếu someValuetruthyfalsenếu someValuefalsy , đó là dễ dàng hơn để quản lý.

Thảo luận

Bây giờ, tại sao tôi lại bận tâm đến bản thân if (!!someValue)khi một thứ như thế if (someValue)sẽ cho tôi kết quả tương tự?

Bởi vì !!someValuechính xác là một biểu thức boolean, trong khi someValuecó thể hoàn toàn là bất cứ điều gì. Kiểu biểu thức này bây giờ sẽ cho phép viết các hàm (và Chúa chúng ta cần chúng) như:

isSomeValueDefined(): boolean {
  return !!someValue
}

thay vì:

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

Tôi hy vọng nó sẽ giúp.


vì vậy, nếu someValue là 'false' (với kiểu chuỗi), thì !! someValue là false (kiểu boolean)?
paul cheung

Tôi đoán bạn có thể nói như vậy. Kỹ thuật này được sử dụng chính xác để tránh có loại nhầm lẫn này. Tôi hy vọng bạn thích nó!
avi.elkharrat

nhưng điều làm tôi bối rối là !! 'sai' bằng với sự thật. Chỉ vì trường hợp này, tôi không thể sử dụng kỹ thuật này.
paul cheung

!!'false'là trong chứng thư true'false'là một chuỗi hợp lệ
avi.elkharrat

Vì vậy, kỹ thuật này không thể bao gồm trường hợp này, hoặc có một giải pháp khắc phục?
paul cheung

16

Đối với Typescript 2.x.xbạn nên làm theo cách sau (sử dụng loại bảo vệ ):

tl; dr

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

Tại sao?

Theo cách isDefined()này sẽ tôn trọng loại biến và mã sau đây sẽ biết kiểm tra tài khoản này.

Ví dụ 1 - kiểm tra cơ bản:

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

Ví dụ 2 - loại tôn trọng:

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

nó có nghĩa là dữ liệu

  • vô giá trị
  • chưa xác định
  • sai
  • ....

2
Và nếu dữ liệu thuộc loại boolean?
ianstigator

bạn có thể kết hợp hai biến, ví dụ. if (value1 && value2) để kiểm tra xem cả hai đều không xác định?
ARK

@ianstigator Một boolean có thể được đánh giá là truehoặc falsechỉ. Nếu bạn có một boolean với một phép nullgán hoặc một undefinedgiá trị, trong cả hai trường hợp, giá trị sẽ được đánh giá là false.
KBeDev

5

Nếu bạn đang sử dụng TypeScript, cách tốt hơn là để trình biên dịch kiểm tra null và không xác định (hoặc khả năng của chúng), thay vì kiểm tra chúng vào thời gian chạy. (Nếu bạn muốn kiểm tra vào thời gian chạy, thì càng nhiều câu trả lời chỉ ra, chỉ cần sử dụng value == null).

Sử dụng tùy chọn biên dịch strictNullChecksđể báo cho trình biên dịch bóp nghẹt các giá trị null hoặc không xác định có thể. Nếu bạn đặt tùy chọn này, và sau đó là một tình huống mà bạn làm muốn cho phép null và undefined, bạn có thể xác định loại như Type | null | undefined.


5

Nếu bạn muốn vượt qua tslintmà không cần thiết strict-boolean-expressionsphải allow-null-unionhay allow-undefined-union, bạn cần phải sử dụng isNullOrUndefinedtừ node's utilmô-đun hoặc cuộn của riêng bạn:

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

Không chính xác đường cú pháp nhưng hữu ích khi quy tắc tslint của bạn nghiêm ngặt.


1

Một ký hiệu nhanh hơn và ngắn hơn để nullkiểm tra có thể là:

value == null ? "UNDEFINED" : value

Dòng này tương đương với:

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

Đặc biệt khi bạn có nhiều nullkiểm tra thì đó là một ký hiệu ngắn đẹp.


1

Tôi đã có vấn đề này và một số câu trả lời hoạt động tốt JSnhưng không phải vì TSlý do ở đây.

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

Đó là tất cả tốt vì JS không có loại

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

Trong TS nếu biến không được định nghĩa với nullkhi bạn cố gắng để kiểm tra rằng nullcác tslint| trình biên dịch sẽ khiếu nại.

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

Việc tham gia chuỗi này muộn nhưng tôi thấy việc hack JavaScript này rất tiện lợi trong việc kiểm tra xem giá trị có được xác định không

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

1

Thông thường tôi làm kiểm tra tung hứng như Fenton đã thảo luận . Để dễ đọc hơn, bạn có thể sử dụng isNil từ ramda.

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

totalAmount = isNil(totalAmount ) ? 0 : totalAmount ;

1

Như một cách tiết, nếu bạn muốn so sánh rỗngkhông xác định giá trị CHỈ , sử dụng mã ví dụ sau đây để tham khảo:

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

Nếu incomingValuekhông được khai báo, TypeScript sẽ trả về một ngoại lệ. Nếu điều này được khai báo nhưng không được xác định,console.log() sẽ trả về "Giá trị đến là: không xác định". Lưu ý chúng tôi không sử dụng toán tử bằng nghiêm ngặt.

Cách "chính xác" (kiểm tra các câu trả lời khác để biết chi tiết), nếu đó incomingValuekhông phải là một booleanloại, chỉ cần đánh giá nếu giá trị của nó là đúng, điều này sẽ được đánh giá theo loại hằng / biến. Một truechuỗi phải được xác định rõ ràng là chuỗi bằng cách sử dụng phép = ''gán. Nếu không, nó sẽ được đánh giá là false. Hãy kiểm tra trường hợp này bằng cách sử dụng cùng một bối cảnh:

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 == (không xác định | | null). (không xác định | | null) giải quyết thành null, do đó, đây là một so sánh lỏng lẻo giữa
SomethingToCompare

@carlosvini Chắc chắn, điểm so sánh là dài dòng và cung cấp mã để tham khảo. Đó là lý do của sự so sánh không nghiêm ngặt bằng. Mục đích của câu trả lời là rõ ràng và có tính khám phá. Tôi sẽ chỉnh sửa văn bản để tránh nhầm lẫn
KBeDev


0

Tất cả,

Câu trả lời có nhiều phiếu nhất, không thực sự hiệu quả nếu bạn đang làm việc với một đối tượng. Trong trường hợp đó, nếu một tài sản không có mặt, kiểm tra sẽ không hoạt động. Và đó là vấn đề trong trường hợp của chúng tôi: xem mẫu này:

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

Kết quả:

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

liên kết plunkr: https://plnkr.co/edit/BJpVHD95FhKlpHp1skUE


Đây không phải là bài kiểm tra tốt. Không có giá trị nào trong số đó là đúng null . Hãy thử điều này: plnkr.co/edit/NfiVnQNes1p8PvXd1fCG?p=preview
simonhamp

0

Vì TypeScript là một siêu ký tự gõ của ES6 JavaScript. Và lodash là một thư viện của javascript.

Sử dụng lodash để kiểm tra nếu giá trị là null hoặc không xác định có thể được thực hiện bằng cách sử dụng _.isNil().

_.isNil(value)

Tranh luận

giá trị (*): Giá trị cần kiểm tra.

Trả về

(boolean) : Trả về true nếu giá trị là nullish, khác false.

Thí dụ

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

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

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

Liên kết

Tài liệu tạm thời


1
Tại sao phương pháp này là -2? Lodash không tốt với loại kịch bản?
Thomas Poignant

0

cẩn thận nếu bạn đang sử dụng bộ nhớ cục bộ, bạn có thể kết thúc bằng chuỗi không xác định thay vì giá trị không xác định:

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

Mọi người có thể thấy điều này hữu ích: 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

Tôi luôn viết nó như thế này:

var foo:string;

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

Điều này sẽ hoạt động tốt và tôi nghĩ rằng nó rất dễ đọc.


21
Sẽ không làm việc cho các số vì 0cũng vượt qua !foobài kiểm tra.
hasen

10
Không hoạt động cho booleans, nơi undefinedkhác với false. Điều này rất phổ biến với các tham số hàm boolean tùy chọn, trong đó bạn nên sử dụng cách tiếp cận JavaScript phổ biến:function fn(flag?: boolean) { if (typeof flag === "undefined") flag = true; /* set default value */ }
Gingi

Có vẻ hoạt động tốt cho booleans : var isTrue; if(isTrue)//skips, if(!isTrue)// enters if(isTrue === undefined)//enters. Cũng đã thử nó trong bản in var isTrue:booleanmà không được xác định, và tương tự nếu kiểm tra. @Gingi, có gì khác về những gì bạn đã thử và những gì tôi đã thử không?
Drenai
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.