601 Stimmen

Unterstützt TypeScript den ?. Operator? (Und, wie wird er genannt?)

Unterstützt Typescript derzeit (oder gibt es Pläne dafür) den sicheren Navigations Operator von ?.?

d.h.:

var thing = foo?.bar
// das Gleiche wie:
var thing = (foo) ? foo.bar : null;

Gibt es auch einen gebräuchlicheren Namen für diesen Operator (es ist unglaublich schwer, danach zu googeln).

2voto

Damian Green Punkte 5851

Es wird als optionales Kettenieren bezeichnet und es ist in Typescript 3.7

Optionales Kettenieren ermöglicht es uns, Code zu schreiben, bei dem wir sofort aufhören können, einige Ausdrücke auszuführen, wenn wir auf ein Null oder Undefined stoßen

0voto

Benny Bottema Punkte 10255

Wie bereits erwähnt, wird derzeit noch darüber nachgedacht, aber es ist bereits seit einigen Jahren eingefroren.

Aufbauend auf den vorhandenen Antworten, hier ist die prägnanteste manuelle Version, die mir einfällt:

jsfiddle

function val(valueSupplier: () => T): T {
  try { return valueSupplier(); } catch (err) { return undefined; }
}

let obj1: { a?: { b?: string }} = { a: { b: 'c' } };
console.log(val(() => obj1.a.b)); // 'c'

obj1 = { a: {} };
console.log(val(() => obj1.a.b)); // undefined
console.log(val(() => obj1.a.b) || 'Nothing'); // 'Nothing'

obj1 = {};
console.log(val(() => obj1.a.b) || 'Nothing'); // 'Nothing'

obj1 = null;
console.log(val(() => obj1.a.b) || 'Nothing'); // 'Nothing'

Es scheitert einfach still bei fehlenden Eigenschaftsfehlern. Es greift auf die Standard-Syntax zurück, um den Standardwert zu bestimmen, der auch komplett weggelassen werden kann.


Obwohl dies für einfache Fälle funktioniert, werden bei komplexeren Dingen wie dem Aufruf einer Funktion und anschließendem Zugriff auf eine Eigenschaft des Ergebnisses auch andere Fehler verschluckt. Schlechtes Design.

In dem obigen Fall ist eine optimierte Version der anderen hier geposteten Antwort die bessere Option:

jsfiddle

function o(obj?: T, def: T = {} as T): T {
    return obj || def;
}

let obj1: { a?: { b?: string }} = { a: { b: 'c' } };
console.log(o(o(o(obj1).a)).b); // 'c'

obj1 = { a: {} };
console.log(o(o(o(obj1).a)).b); // undefined
console.log(o(o(o(obj1).a)).b || 'Nothing'); // 'Nothing'

obj1 = {};
console.log(o(o(o(obj1).a)).b || 'Nothing'); // 'Nothing'

obj1 = null;
console.log(o(o(o(obj1).a)).b || 'Nothing'); // 'Nothing'

Ein komplexeres Beispiel:

o(foo(), []).map((n) => n.id)

Sie können auch den anderen Weg gehen und etwas wie Lodash' _.get() verwenden. Es ist prägnant, allerdings kann der Compiler die Gültigkeit der verwendeten Eigenschaften nicht beurteilen:

console.log(_.get(obj1, 'a.b.c'));

0voto

Jamon Holmgren Punkte 22240

Noch nicht (Stand September 2019), aber da der "sichere Navigationsoperator" jetzt in Stadium 3 ist, wird er in TypeScript implementiert.

Beobachten Sie dieses Problem für Updates:

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

Mehrere Engines haben frühe Implementierungen:

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

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

Sie können jetzt ein Plugin installieren, um es zu unterstützen:

npm install --save-dev ts-optchain

In Ihrer tsconfig.json:

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

Ich gehe davon aus, dass diese Antwort in den nächsten 6 Monaten veraltet sein wird, aber hoffentlich wird sie in der Zwischenzeit jemandem helfen.

0voto

Ich glaube, das ist wonach Sie suchen. Ähnliches Beispiel unter Powerbite

/**
 * Typsicherer Zugriff auf tiefe Eigenschaft eines Objekts
 *
 * @param obj                   Objekt, auf das die tiefe Eigenschaft zugegriffen werden soll
 * @param unsafeDataOperation   Funktion, die die tiefe Eigenschaft zurückgibt
 * @param valueIfFail           Wert, der zurückgegeben werden soll, falls die Eigenschaft nicht existiert
 */
export function getInSafe(obj: O, unsafeDataOperation: (x: O) => T, valueIfFail?: any) : T {
    try {
        return unsafeDataOperation(obj)
    } catch (error) {
        return valueIfFail;
    }
}

//Beispielverwendung:
getInSafe(sellTicket, x => x.phoneDetails.imeiNumber, '');

//Beispiel von oben
getInSafe(foo, x => x.bar.check, null);

-1voto

Angelos Pikoulas Punkte 975

_.get(obj, 'address.street.name') funktioniert großartig für JavaScript, wo Sie keine Typen haben. Aber für TypeScript brauchen wir den echten Elvis-Operator!

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X