Bir türü TypeScript'te nullable olarak nasıl bildiririm?


249

TypeScript'te bir arayüz var.

interface Employee{
    id: number;
    name: string;
    salary: number;
}

yapmak isterim salaryBoş bir alan olarak (C # 'da yapabileceğimiz gibi). Bu, TypeScript'te yapmak mümkün mü?

Yanıtlar:


277

JavaScript'teki (ve TypeScript'teki) tüm alanların değeri olabilir nullveyaundefined .

Alanı , boş değerden farklı olan isteğe bağlı yapabilirsiniz .

interface Employee1 {
    name: string;
    salary: number;
}

var a: Employee1 = { name: 'Bob', salary: 40000 }; // OK
var b: Employee1 = { name: 'Bob' }; // Not OK, you must have 'salary'
var c: Employee1 = { name: 'Bob', salary: undefined }; // OK
var d: Employee1 = { name: null, salary: undefined }; // OK

// OK
class SomeEmployeeA implements Employee1 {
    public name = 'Bob';
    public salary = 40000;
}

// Not OK: Must have 'salary'
class SomeEmployeeB implements Employee1 {
    public name: string;
}

İle karşılaştırmak:

interface Employee2 {
    name: string;
    salary?: number;
}

var a: Employee2 = { name: 'Bob', salary: 40000 }; // OK
var b: Employee2 = { name: 'Bob' }; // OK
var c: Employee2 = { name: 'Bob', salary: undefined }; // OK
var d: Employee2 = { name: null, salary: 'bob' }; // Not OK, salary must be a number

// OK, but doesn't make too much sense
class SomeEmployeeA implements Employee2 {
    public name = 'Bob';
}

35
Görünüşe göre kesinlikle null olabilecek türler ve sıkı null kontroller uygulanmış ve Typescript 2.0 ile gelecek! (veya typescript@nextşimdi.)
mindplay.dk

ilk örnekte var c hakkında emin misiniz? Bana öyle geliyor ki var b ve var c aynı.
martinp999

Derleme hatası olmadan null veya undefined değeri ayarlamak için tsconfig "katı" seçeneği kaldırılmalı veya "yanlış" değerine eşit olmalıdır"strict" : false
Nicolas Janel

1
Bu yanlış. JS null ve undefined arasında ayrım yapar. Doğru kod olmalıdır salary:number|null;Eğer yaparsanız salary?:number; salary = null;bir hata alırsınız. Ancak, salary = undefined;bu durumda gayet iyi çalışacaktır. Çözüm: Birlik yani '|' kullanın
Ankur Nigam

126

Sendika türü bence bu durumda en iyi seçenektir:

interface Employee{
   id: number;
   name: string;
   salary: number | null;
}

// Both cases are valid
let employe1: Employee = { id: 1, name: 'John', salary: 100 };
let employe2: Employee = { id: 1, name: 'John', salary: null };

DÜZENLEME: Bu çalışmaya beklendiği gibi için, imkan vermelidir strictNullChecksiçinde tsconfig.


9
--StrictNullChecks (kullanmanız gerekir) kullanırsanız, bu geçerli bir çözümdür. İsteğe bağlı üyeler lehine kullanmazdım, çünkü sizi tüm değişmez nesnelere açık bir null eklemeye zorlar, ancak işlev dönüş değerleri için bu yoludur.
geon

78

Daha fazla C # gibi olmak için, Nullabletürü şu şekilde tanımlayın :

type Nullable<T> = T | null;

interface Employee{
   id: number;
   name: string;
   salary: Nullable<number>;
}

Bonus:

NullableYerleşik dizgi türü gibi davranmak için global.d.ts, kök kaynak klasöründeki bir tanım dosyasında tanımlayın . Bu yol benim için çalıştı:/src/global.d.ts


1
En sevdiğim cevap - soruyu okumadan doğrudan cevaplar.
Lqueryvg

1
Bunu kullanmak, nesne özelliklerinin otomatik olarak tamamlanmasını keser. Elimizdeki Örneğin emp: Partial<Employee>, yapabileceğimiz emp.idveya emp.namevs ama biz varsa emp: Nullable<Employee>, biz yapamazemp.id
Yusuf Karaca

1
Bu sorunun asıl cevabı bu.
Patrick

37

?İsteğe bağlı alana bir soru işareti eklemeniz yeterlidir.

interface Employee{
   id: number;
   name: string;
   salary?: number;
}

54
Ryan'ın işaret ettiği gibi ...? daktiloda isteğe bağlı anlamına gelir, boş değerli değildir. Olmadan? var değerinin null veya undefined dahil bir değere ayarlanması gerektiği anlamına gelir. İle ? tüm bildirimi atlayabilirsiniz.
O Nrik

3
Teşekkür ederim! Ben tam olarak ne aradığını bu yüzden "typescript isteğe bağlı değer" için googled .
Diğer Yabancı

13

Yalnızca aşağıdaki gibi kullanıcı tanımlı bir tür uygulayabilirsiniz:

type Nullable<T> = T | undefined | null;

var foo: Nullable<number> = 10; // ok
var bar: Nullable<number> = true; // type 'true' is not assignable to type 'Nullable<number>'
var baz: Nullable<number> = null; // ok

var arr1: Nullable<Array<number>> = [1,2]; // ok
var obj: Nullable<Object> = {}; // ok

 // Type 'number[]' is not assignable to type 'string[]'. 
 // Type 'number' is not assignable to type 'string'
var arr2: Nullable<Array<string>> = [1,2];

10
type MyProps = {
  workoutType: string | null;
};

4

Ben bir süre önce aynı soru vardı .. ts tüm türleri nullable, çünkü void tüm türlerin bir alt türü (aksine, scala).

bu akış şemasının yardımcı olup olmadığına bakın - https://github.com/bcherny/language-types-comparison#typescript


2
-1: Bu hiç doğru değil. Gelince void'her türlü alt türü' (varlık alt türü ), bakınız bu konuya . Ayrıca scala için sağladığınız grafik de yanlıştır. Nothingscala'da aslında alt tiptir. Typescript, atm, gelmez skala ise alt türü var yok .
Daniel Shin

2
"Her tür alt tür"! = Alt tür. TS spesifikasyonuna buradan bakın github.com/Microsoft/TypeScript/blob/master/doc/…
bcherny

3

Null olabilecek tür çalışma zamanı hatasına neden olabilir. Bu yüzden bir derleyici seçeneği kullanmak --strictNullChecksve number | nulltür olarak bildirmek iyi olduğunu düşünüyorum . ayrıca iç içe fonksiyon durumunda, giriş türü null olmasına rağmen, derleyici ne kıracağını bilemez, bu yüzden kullanmanızı öneririz !(ünlem işareti).

function broken(name: string | null): string {
  function postfix(epithet: string) {
    return name.charAt(0) + '.  the ' + epithet; // error, 'name' is possibly null
  }
  name = name || "Bob";
  return postfix("great");
}

function fixed(name: string | null): string {
  function postfix(epithet: string) {
    return name!.charAt(0) + '.  the ' + epithet; // ok
  }
  name = name || "Bob";
  return postfix("great");
}

Referans. https://www.typescriptlang.org/docs/handbook/advanced-types.html#type-guards-and-type-assertions

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.