495

Typescript は現在、安全なナビゲーション演算子をサポートしていますか (またはサポートする計画がありますか?)?.

すなわち:

var thing = foo?.bar
// same as:
var thing = (foo) ? foo.bar : null;

また、この演算子にはもっと一般的な名前がありますか (Google で検索するのは非常に困難です)。

4

15 に答える 15

287

はい。TypeScript 3.7 ( 2019 年 11 月 5 日にリリース) の時点で、この機能がサポートされており、 Optional Chainingと呼ばれています。

null本質的に、オプションの連鎖により、または に遭遇した場合に TypeScript がいくつかの式の実行をすぐに停止できるコードを記述できますundefined。オプションの連鎖の主役は、オプションのプロパティ アクセス?.の新しい演算子です。

詳細については、TypeScript 3.7 リリース ノートを参照してください。


バージョン 3.7 より前では、これは TypeScript でサポートされていませんでしたが、TypeScript リポジトリ(2014 年にさかのぼる) の第 16 号で要求されました。

この演算子を何と呼ぶか​​については、コンセンサスがないようです。"optional chaining" (これはJavaScript で呼ばれるものでもあります) に加えて、他にもいくつかの例があります:

  • CoffeeScript では、これを存在演算子(具体的には、存在演算子の「アクセサー バリアント」) と呼んでいます。

存在演算子のアクセサー バリアントを?.使用して、一連のプロパティに null 参照を吸収できます。.ベース値がnullまたはundefinedである可能性がある場合は、ドット アクセサーの代わりに使用します。

null 条件演算子は、そのオペランドが非 null と評価される場合にのみ、そのオペランドにメンバー アクセス?.、または要素アクセス、操作を適用します。?[]それ以外の場合は、 を返しますnull

他にもたくさんの例がありそうです。

于 2013-03-07T00:21:21.980 に答える
154

ユーザー「Donut」の回答を参照してください。

古い答え: ブール演算子に関する標準の JavaScript の動作には、役立つ可能性があるものがあります。ブール値メソッドは、オブジェクトを比較するときに true または false を返しませんが、OR の場合は true に等しい最初の値を返します。

単一の ? ほど良くはありませんが、機能します。

var thing = foo && foo.bar || null;

&& は好きなだけ使用できます。

var thing = foo && foo.bar && foo.bar.check && foo.bar.check.x || null;

デフォルト値も可能です:

var name = person && person.name || "Unknown user";
于 2013-03-08T12:34:45.250 に答える
115

これは ECMAScript Optional Chaining 仕様で定義されているため、これについて議論するときはおそらくオプションの連鎖を参照する必要があります。考えられる実装:

const result = a?.b?.c;

要するに、TypeScript チームは ECMAScript 仕様が強化されるのを待っているということです。そのため、将来的に実装が非互換になる可能性があります。彼らが今何かを実装した場合、ECMAScript が仕様を再定義した場合、大きな変更が必要になるでしょう。

オプションの連鎖仕様を参照してください

何かが標準の JavaScript になることは決してない場合、TypeScript チームは適切と思われる方法で実装できますが、将来の ECMAScript の追加のために、他の多くの機能と同様に、早期アクセスを提供する場合でもセマンティクスを維持したいと考えています。

ショートカット

したがって、次のような型変換を含む、JavaScript のファンキーな演算子はすべて利用できます...

var n: number = +myString; // convert to number
var b: bool = !!myString; // convert to bool

手動ソリューション

しかし、質問に戻ります。JavaScript(したがってTypeScript)で同様のことを行う方法の鈍い例がありますが、あなたが本当に求めている機能としてそれが優雅であることを絶対に示唆しているわけではありません.

(foo||{}).bar;

したがって、fooundefined結果でundefinedあり、fooが定義されていて、値を持つという名前のプロパティbarがある場合、結果はその値になります。

JSFiddle に例を載せました。

これは、長い例では非常に大雑把に見えます。

var postCode = ((person||{}).address||{}).postcode;

チェーン機能

仕様がまだ決まっていない間に短いバージョンがどうしても必要な場合は、この方法を使用する場合があります。式を評価し、チェーンが満たされない場合、または null/undefined になる場合はデフォルトを返します (!=ここでは が重要であることに注意してください。ここでは少しポジティブなジャグリングが必要なため、使用したくありません)。!==

function chain<T>(exp: () => T, d: T) {
    try {
        let val = exp();
        if (val != null) {
            return val;
        }
    } catch { }
    return d;
}

let obj1: { a?: { b?: string }} = {
    a: {
        b: 'c'
    }
};

// 'c'
console.log(chain(() => obj1.a.b, 'Nothing'));

obj1 = {
    a: {}
};

// 'Nothing'
console.log(chain(() => obj1.a.b, 'Nothing'));

obj1 = {};

// 'Nothing'
console.log(chain(() => obj1.a.b, 'Nothing'));

obj1 = null;

// 'Nothing'
console.log(chain(() => obj1.a.b, 'Nothing'));
于 2013-03-07T06:27:46.573 に答える
107

更新: はい、現在サポートされています!

TypeScript 3.7 でリリースされたばかりです: https://devblogs.microsoft.com/typescript/announce-typescript-3-7/

オプションの連鎖と呼ばれます: https://devblogs.microsoft.com/typescript/announce-typescript-3-7/#optional-chaining

それと、次のとおりです。

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

次と同等です。

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

古い答え

あなたの意見/要望を声に出すことができる github で、これに対するオープンな機能要求があります: https://github.com/Microsoft/TypeScript/issues/16

于 2015-02-12T04:53:45.363 に答える
41

2019年11月13日編集!

2019 年 11 月 5 日の時点で TypeScript 3.7 が出荷され、オプションの連鎖演算子がサポートされるようになりました!!! ?.

https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#optional-chaining


歴史的な目的のみ:

編集: fracz コメントのおかげで回答を更新しました。

TypeScript 2.0 リリース(C#!.の Safe Navigator) と同じではありません?.

詳細については、この回答を参照してください。

https://stackoverflow.com/a/38875179/1057052

これは、値が null または未定義ではないことをコンパイラに伝えるだけです。これは、値が null または未定義であるかどうかをチェックしません。

TypeScript 非 null アサーション演算子

// Compiled with --strictNullChecks
function validateEntity(e?: Entity) {
    // Throw exception if e is null or invalid entity
}

function processEntity(e?: Entity) {
    validateEntity(e);
    let s = e!.name;  // Assert that e is non-null and access name
}
于 2016-11-01T13:27:37.813 に答える
0

まだ (2019 年 9 月現在) ではありませんが、「安全なナビゲーション オペレーター」は現在 Stage 3であるため、TypeScript で実装されています。

更新については、この号をご覧ください。

https://github.com/microsoft/TypeScript/issues/16

いくつかのエンジンには初期の実装があります:

JSC: https://bugs.webkit.org/show_bug.cgi?id=200199

V8: https://bugs.chromium.org/p/v8/issues/detail?id=9553

SM: https://bugzilla.mozilla.org/show_bug.cgi?id=1566143

( https://github.com/tc39/proposal-optional-chaining/issues/115#issue-475422578経由)

今すぐサポートするプラグインをインストールできます。

npm install --save-dev ts-optchain

tsconfig.json で:

// tsconfig.json
{
    "compilerOptions": {
        "plugins": [
            { "transform": "ts-optchain/transform" },
        ]
    },
}

この回答は今後 6 か月ほどで時代遅れになると思いますが、その間に誰かの役に立てば幸いです。

于 2019-09-30T15:55:57.967 に答える