Est-ce que Typescript supporte le?. opérateur? (Et comment ça s’appelle?)

Est-ce que Typescript supporte actuellement (ou prévoit de le faire) l’opérateur de navigation sécurisé de ?.

c’est à dire:

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

En outre, existe-t-il un nom plus commun pour cet opérateur (il est incommensurable pour Google).

Je ne trouve aucune référence à celle-ci dans la spécification du langage TypeScript .

Pour ce qui est de savoir comment appeler cet opérateur dans CoffeeScript, il s’appelle l’ opérateur existentiel (en particulier, la “variante d’access” de l’opérateur existentiel).

De la documentation de CoffeeScript sur les opérateurs :

La variante d’access de l’opérateur existentiel ?. peut être utilisé pour absorber des références nulles dans une chaîne de propriétés. Utilisez-le à la place du point d’access . dans les cas où la valeur de base peut être nulle ou non définie .

Ainsi, la variante d’accesseur de l’opérateur existentiel semble être la bonne façon de faire référence à cet opérateur; et TypeScript ne semble pas actuellement le supporter (bien que d’ autres aient exprimé leur souhait pour cette fonctionnalité ).

Pas aussi beau qu’un single, mais ça marche:

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

Vous pouvez utiliser autant de && que vous le souhaitez:

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

Ceci est défini dans la spécification ECMAScript Optional Chaining, nous devrions donc probablement nous référer au chaînage facultatif lorsque nous en discuterons. Mise en œuvre probable:

 const result = a?.b?.c; 

La longue et courte de celle-ci est que l’équipe TypeScript attend la spécification ECMAScript pour être renforcée, de sorte que leur implémentation peut être ininterrompue à l’avenir. S’ils implémentaient quelque chose maintenant, cela nécessiterait des modifications majeures si ECMAScript redéfinit leurs spécifications.

Voir les spécifications de chaînage facultatives

Là où quelque chose ne va jamais être le JavaScript standard, l’équipe TypeScript peut implémenter comme bon leur semble, mais pour les futurs ajouts d’ECMAScript, ils veulent préserver la sémantique même s’ils offrent un access précoce, comme pour beaucoup d’autres fonctionnalités.

Coupes courtes

Ainsi, tous les opérateurs JavaScripts sont disponibles, y compris les conversions de type telles que …

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

Solution manuelle

Mais revenons à la question. J’ai un exemple obtus de ce que vous pouvez faire en JavaScript (et donc en TypeScript), bien que je ne suggère pas que ce soit une caractéristique gracieuse comme celle que vous recherchez.

 (foo||{}).bar; 

Donc, si foo n’est undefined le résultat n’est undefined et si foo est défini et a une propriété nommée bar qui a une valeur, le résultat est cette valeur.

Je mets un exemple sur JSFiddle .

Cela semble assez sommaire pour des exemples plus longs.

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

Fonction de chaîne

Si vous êtes désespéré pour une version plus courte alors que la spécification est encore en suspens, j’utilise cette méthode dans certains cas. Il évalue l’expression et retourne une valeur par défaut si la chaîne ne peut pas être satisfaite ou se termine par une valeur nulle / non définie (notez que le != Est important ici, nous ne voulons pas utiliser !== car nous voulons un peu de jonglage positif ici) ).

 function chain(exp: () => T, d: T) { try { let val = exp(); if (val != null) { return val; } } catch { } return d; } let obj1: { a?: { b?: ssortingng }} = { a: { b: 'c' } }; // 'c' console.log(chain(() => obj1.ab, 'Nothing')); obj1 = { a: {} }; // 'Nothing' console.log(chain(() => obj1.ab, 'Nothing')); obj1 = {}; // 'Nothing' console.log(chain(() => obj1.ab, 'Nothing')); obj1 = null; // 'Nothing' console.log(chain(() => obj1.ab, 'Nothing')); 

Il y a une demande de fonctionnalité ouverte pour cela sur github où vous pouvez exprimer votre opinion / désir: https://github.com/Microsoft/TypeScript/issues/16

Edit: J’ai mis à jour la réponse grâce à fracz comment.

TypeScript 2.0 est disponible !. Ce n’est pas la même chose que ?. (Safe Navigator en C #)

Voir cette réponse pour plus de détails:

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

Cela indiquera uniquement au compilateur que la valeur n’est pas nulle ou indéfinie. Cela ne vérifiera pas si la valeur est nulle ou non définie.

Opérateur d’assertion non null de typeScript

 // Comstackd with --ssortingctNullChecks 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 } 

Opérateur ?. n’est pas pris en charge dans la version 2.0 de TypeScript.

Donc j’utilise la fonction suivante:

 export function o(someObject: T, defaultValue: T = {} as T) : T { if (typeof someObject === 'undefined' || someObject === null) return defaultValue; else return someObject; } 

l’utilisation ressemble à ceci:

 o(o(o(test).prop1).prop2 

De plus, vous pouvez définir une valeur par défaut:

 o(o(o(o(test).prop1).prop2, "none") 

Cela fonctionne très bien avec IntelliSense dans Visual Studio.

Nous avons créé cette méthode util pendant que nous travaillons sur Phonetradr, ce qui peut vous donner un access sécurisé aux propriétés profondes avec Typescript:

 /** * Type-safe access of deep property of an object * * @param obj Object to get deep property * @param unsafeDataOperation Function that returns the deep property * @param valueIfFail Value to return in case if there is no such property */ export function getInSafe(obj: O, unsafeDataOperation: (x: O) => T, valueIfFail?: any) : T { try { return unsafeDataOperation(obj) } catch (error) { return valueIfFail; } } //Example usage: getInSafe(sellTicket, x => x.phoneDetails.imeiNumber, ''); //Example from above getInSafe(foo, x => x.bar.check, null); 

Comme il a déjà été répondu, il est actuellement encore à l’étude, mais il est mort dans l’eau depuis quelques années.

En me basant sur les réponses existantes, voici la version du manuel la plus concise que je puisse imaginer:

jsfiddle

 function val(valueSupplier: () => T): T { try { return valueSupplier(); } catch (err) { return undefined; } } let obj1: { a?: { b?: ssortingng }} = { a: { b: 'c' } }; console.log(val(() => obj1.ab)); // 'c' obj1 = { a: {} }; console.log(val(() => obj1.ab)); // undefined console.log(val(() => obj1.ab) || 'Nothing'); // 'Nothing' obj1 = {}; console.log(val(() => obj1.ab) || 'Nothing'); // 'Nothing' obj1 = null; console.log(val(() => obj1.ab) || 'Nothing'); // 'Nothing' 

Il échoue simplement en silence sur les erreurs de propriété manquantes. Il revient à la syntaxe standard pour déterminer la valeur par défaut, qui peut également être omise complètement.


Bien que cela fonctionne pour des cas simples, si vous avez besoin de choses plus complexes, comme appeler une fonction puis accéder à une propriété du résultat, toutes les autres erreurs sont également avalées. Mauvaise conception.

Dans le cas ci-dessus, une version optimisée de l’autre réponse affichée ici est la meilleure option:

jsfiddle

 function o(obj?: T, def: T = {} as T): T { return obj || def; } let obj1: { a?: { b?: ssortingng }} = { 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' 

Un exemple plus complexe:

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

Vous pouvez également aller dans l’autre sens et utiliser quelque chose comme Lodash ‘ _.get() . C’est concis, mais le compilateur ne pourra pas juger de la validité des propriétés utilisées:

 console.log(_.get(obj1, 'abc')); 

Dans la version 2.9 prend en charge! https://github.com/Microsoft/TypeScript/wiki/What%27s-new-in-TypeScript#non-null-assertion-operator

 const a = {} console.log(a!.b!.c) 

aucune option supplémentaire requirejse dans .tsconfig