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.