TypeScriptで型をnull許容として宣言するにはどうすればよいですか?


248

TypeScriptにインターフェイスがあります。

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

salarynull可能なフィールドとして作成したいと思います(C#でできるように)。TypeScriptでこれは可能ですか?

回答:


275

JavaScript(およびTypeScript)のすべてのフィールドは、値nullorを持つことができますundefined

nullableとは異なるフィールドをオプションにすることができます。

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

と比べて:

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
以下のようになります。厳密にNULL可能なタイプと厳格なヌル・チェックが実施されていると活字体2.0で到着します!(またはtypescript@next現在)
mindplay.dk

最初の例でvar cについて確信がありますか?var bとvar cは同じであるように私には思えます。
martinp999

コンパイルエラーなしでnullまたは未定義の値を設定するには、tsconfigの「strict」オプションを削除するか、「false」に等しくする必要があります"strict" : false
Nicolas Janel

1
これは誤りです。JSはnullと未定義を区別します。正しいコードはする必要がありますsalary:number|null;その場合はsalary?:number; salary = null;あなたがエラーを取得します。ただし、salary = undefined;この場合は問題なく動作します。解決策:ユニオン、つまり '|'を使用します
Ankur Nigam

125

この場合、ユニオン型が私の心の中で最良の選択肢です。

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

編集:これを期待どおりに機能させるには、を有効にする必要がstrictNullChecksありtsconfigます。


9
--strictNullChecksを使用する場合(必要です)、これは有効なソリューションです。すべてのリテラルオブジェクトに明示的なnullを追加する必要があるため、オプションのメンバーを優先して使用しませんが、関数の戻り値の場合は、それが適切です。
geon 2016年

78

よりC#のようにするには、次のようにNullable型を定義します。

type Nullable<T> = T | null;

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

ボーナス:

Nullable組み込みのTypescriptタイプのように動作させるにglobal.d.tsは、ルートソースフォルダーの定義ファイルで定義します。このパスは私にとってうまくいきました:/src/global.d.ts


1
私のお気に入りの答え- 質問を読まずに直接答えます。
Lqueryvg

1
これを使用すると、オブジェクトプロパティのオートコンプリートが無効になります。我々が持っている場合たとえばemp: Partial<Employee>、我々は行うことができますemp.idemp.nameなどが、我々が持っている場合emp: Nullable<Employee>、我々は行うことはできませんemp.id
ユースフ・カーン

1
これが質問に対する実際の答えです。
パトリック

36

?オプションのフィールドに疑問符を追加するだけです。

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

54
ライアンが指摘したように...?typescriptではオプションで、null可能ではありません。なし?varはnullまたは未定義を含む値に設定する必要があることを意味します。とは?宣言全体をスキップできます。
彼のNrikは、2015

3
ありがとうございました!私は「typescriptオプション値」を探したので、これがまさに私が探していたものです。
フェローストレンジャー

13

次のようなユーザー定義型を実装できます。

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


4

私はしばらく前に同じ質問をしました.. voidはすべての型のサブタイプであるため(たとえば、scalaとは異なり)、tsのすべての型はnull可能です。

このフローチャートが役立つかどうかを確認してください-https://github.com/bcherny/language-types-comparison#typescript


2
-1:これはまったく当てはまりません。void(「全てのタイプのサブタイプ」はボトム型)を参照してこのスレッド。また、scalaに指定したチャートも正しくありません。NothingScalaでは、実際には一番下のタイプです。Typescript atmは、scala 持っているのに対し、bottomタイプを持ちません
Daniel Shin

2
「すべてのタイプのサブタイプ」!=ボトムタイプ。TSは、ここにスペックを参照してくださいgithub.com/Microsoft/TypeScript/blob/master/doc/...を
bcherny

3

null可能型は実行時エラーを引き起こす可能性があります。したがって、コンパイラオプションを使用--strictNullChecksnumber | null、型として宣言するのが良いと思います。入れ子関数の場合も入力型はnullですが、コンパイラは何が壊れるか分からないので!(感嘆符)の使用をお勧めします。

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

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.