Typescript: Suggestion¬†: "op√©rateur de navigation s√Ľre", c'est-√†-dire x?.y

Cr√©√© le 15 juil. 2014  ¬∑  205Commentaires  ¬∑  Source: microsoft/TypeScript

Statut actuel

  • La proposition TC39 est maintenant √† l'√©tape 3 (ūüéČūüéČūüéČūüéČūüéČ)
  • La mise en Ňďuvre est en cours
  • Vous pouvez vous attendre √† cette fonctionnalit√© dans TypeScript 3.7
  • Nous mettrons √† jour ici quand il sera disponible dans une version nocturne
  • Retarder l'appel facultatif jusqu'√† ce que sa s√©mantique soit clarifi√©e au comit√©

Questions ouvertes

  • Quelle casse sp√©ciale, le cas √©ch√©ant, devrait avoir document.all¬†?

C# et d'autres langages ont un sucre de syntaxe pour acc√©der aux cha√ģnes de propri√©t√©s o√Ļ null (ou dans notre cas, undefined ) peut √™tre rencontr√© √† n'importe quel point de la hi√©rarchie d'objets.

var x = { y: { z: null, q: undefined } };
console.log(x?.y?.z?.foo); // Should print 'null'
console.log(x?.baz); // Still an error
console.log(x.y.q?.bar); // Should print 'undefined'

Besoin d'une proposition sur ce que nous devrions exactement coder, en gardant à l'esprit les effets secondaires des accesseurs.


√Čdit√© par @DanielRosenwasser le 27 f√©vrier 2018¬†: Cette proposition est √©galement appel√©e op√©rateur de "propagation nulle".

Committed ES Next Suggestion Update Docs on Next Release

Commentaire le plus utile

Le cha√ģnage facultatif est l'√©tape 3

Déverrouiller brièvement celui-ci uniquement à des fins de célébration

Tous les 205 commentaires

Ainsi, dans le premier exemple, nous pourrions l'émettre comme suit :

x && xy && xyz && xyzfoo

Mais alors nous devrions faire en sorte que x, y, z et foo évaluent chacun au plus une fois.

Vous ne pouvez pas non plus faire && dans de nombreux cas, car la véracité devient un peu un problème pour les primitifs.

Par exemple:

"     "?.trim()?.indexOf("hello")

donne "" .

Vous devez donc faire des comparaisons explicites avec null en utilisant == pour le cas g√©n√©ral, √† moins que nous ne tirions parti du syst√®me de type (ce qui serait plut√īt cool de nous voir faire).

Nous pourrions éventuellement émettre une fonction de liaison monadique (pas jolie pour la sortie JS), ou utiliser une transformation sur les opérateurs ternaires (plus proche de l'équivalent JS typique). Je suis clairement un peu biaisé envers ce dernier.

:+1:

Idéalement, ES7 (ou ES8 ou ES9 ou ...) implémenterait cela en premier car il y aurait probablement un désaccord sur la sémantique exacte quant à l'utilisation ou non de 0 / "" en tant que fausses primitives pour les besoins de n'importe quel opérateur ici.

:+1: J'aimerais que TypeScript obtienne cela en premier sans avoir à attendre ESxx.

Le fait que des opérateurs de sécurité null simples et incroyablement utiles comme "?." et "?:" NE SONT PAS dans la spécification ES6 signifie que les personnes qui élaborent la spécification ES6 devraient avoir honte. C'est une chose tellement simple et évidente que ne pas l'intégrer serait franchement insensé. Il y a une raison pour laquelle la plupart des langages modernes les prennent en charge : ils sont indispensables.

Je me rends compte que ce serait un écart par rapport à la spécification actuelle (puisque la spécification actuelle est si myope qu'elle omet cela). Mais c'est tellement ridiculement utile que je pense que ce seul écart serait justifié. La grande majorité (VAST) des développeurs TS ne serait pas affectée par des modifications mineures de l'implémentation, si ou quand cela est finalement ajouté à une spécification ES. Les énormes avantages que cela offrirait valent l'impact futur potentiel sur une infime fraction de développeurs. Et étant donné le processus de spécification ES ridiculement lent, cela n'aurait même pas d'importance du tout pendant plusieurs années (au minimum).

Je suis tout à fait d'accord avec brain428

@ brian428 le problème ici est que cet opérateur peut être implémenté dans ES7 donc si le tapuscrit va avec une spécification qui finit par différer de la version finale ES7, personne ne sera content.

le problème ici est que cet opérateur peut être implémenté dans ES7, donc si le tapuscrit va avec une spécification qui finit par différer de la version finale d'ES7, personne ne sera content.

Je pense que c'est une approche plus positive pour TypeScript d'implémenter des fonctionnalités qui peuvent _potentiellement _ (ou non) en faire une future version ES, car ce sera un banc d'essai utile pour influencer la direction ES.

Voici un exemple de discussion ES influencée par TypeScript :

L'option TypeScript... pour déclarer et initialiser via un préfixe privé sur l'un des paramètres du constructeur serait utile à de nombreux développeurs

De plus, il est certainement possible pour ES d'adopter une fonctionnalité déjà présente dans TypeScript, mais avec une sémantique différente (par exemple, autour du fonctionnement des modules).

il est certainement possible pour ES d'adopter une fonctionnalité déjà présente dans TypeScript, mais avec une sémantique différente

Je dois noter que nous consid√©rons g√©n√©ralement qu'il s'agit du pire sc√©nario. Nous voulions vraiment que les modules dans ES6 soient finalis√©s avant de d√©clarer TypeScript 1.0, mais les retards du comit√© l'ont emp√™ch√©. C'est quelque chose √† √©viter, pas √† r√©p√©ter. Nous aimerions vraiment toucher des fonctionnalit√©s qui ont soit ~ 0¬†% de chances d'√™tre int√©gr√©es √† ES7 + (par exemple, les annotations de type), soit environ 100¬†% de chances d'√™tre int√©gr√©es avec une s√©mantique facilement d√©finie (par exemple, o√Ļ la grosse fl√®che √©tait deux il y a des ann√©es). Les nouveaux op√©rateurs sont susceptibles de tomber dans le milieu maladroit.

Dans le pire des cas, si ES7 diff√®re, un indicateur de compilateur pourrait-il prendre en charge l'impl√©mentation TS h√©rit√©e, offrant ainsi une p√©riode de gr√Ęce ? Ceci, associ√© √† une documentation claire sur la migration, devrait offrir aux d√©veloppeurs une voie simple vers toute nouvelle norme.

En fin de compte, l'utilisation d'une telle fonctionnalité, bien qu'incroyablement utile, n'est pas essentielle pour les développeurs. TS devrait rendre les implications futures potentielles de son utilisation très claires dès le premier jour. Vous n'aimez pas l'idée d'un refactoring géré potentiel, ne l'utilisez pas. Peut-être un indicateur de compilateur opt-in pour appliquer ce message ?

TS ne devrait pas se d√©cha√ģner en voulant influencer ES, mais dans de petits cas isol√©s comme celui-ci, il serait dommage que TS se d√©robe compl√®tement.

Peut-être pourrions-nous élaborer une proposition d'homme de paille pour cela, puis avoir une implémentation de référence derrière un drapeau --harmony (ou quelque chose comme ça). De cette façon, nous pouvons piloter le développement ES7 de cette fonctionnalité.

Pour éviter les effets secondaires dus à des recherches répétées, le compilateur devra soit sortir des variables temporaires :

($tmp0 = x, $tmp0 === void 0 ? void 0 : 
    ($tmp1=$tmp0.y,  $tmp1 === void 0 ? void 0 : 
        ($tmp2 = $tmp1.z,  $tmp2 === void 0 ? void 0 : $tmp2)))

ou utilisez une membrane de mémorisation basée sur Proxy .

D'un point de vue cat√©goriel, il ne s'agit que de la monade peut-√™tre appliqu√©e √† la recherche de propri√©t√©, c'est donc une fonctionnalit√© tr√®s naturelle pour un langage o√Ļ toutes les recherches de propri√©t√© peuvent renvoyer undefined. Je serais surpris si ES7 adoptait une s√©mantique autre que celle d√©crite par le code ci-dessus.

La question du codeplex a eu un certain nombre de votes (61)

J'en ai vraiment besoin pour soulager la douleur d'utiliser atom pour atom-typescript .

Il est tr√®s idiomatique dans le code coffescript (bien que j'aimerais qu'il ne soit pas aussi populaire car le d√©terminisme est meilleur qu'un flou ? ). Ouvrez n'importe quel fichier coffescript, en particulier celui qui fonctionne avec le DOM directement comme space-pen (o√Ļ les fonctions peuvent s'ex√©cuter apr√®s la destruction de la vue ou avant que la vue ne soit attach√©e) et vous trouverez un gazillion ? d'utilisations. par exemple, ce fichier a 16 https://github.com/atom-community/autocomplete-plus/blob/f17659ad4fecbd69855dfaf00c11856572ad26e7/lib/suggestion-list-element.coffee

Encore une fois, je n'aime pas avoir besoin de cela, mais c'est l'état de JavaScript, et je préfère ? qu'un million if( && fest ) { then }

Mais j'en ai vraiment vraiment besoin pour garder mon code lisible. Il est également très courant d'en avoir besoin lorsque vous attendez qu'un XHR se termine et que angular exécute sa boucle de digestion.

Bon maintenant j'ai lu le fil et je vois pourquoi nous attendons. Je comprends _soupir_.

we'd have to somehow make x, y, z, and foo each evaluate at most once.

coffeescript fait quelques optimisations, par exemple stocke les résultats d'accès intermédiaires :

typeof foo !== "undefined" && foo !== null ? (ref = foo.bar) != null ? ref.baz() : void 0 : void 0;

(Je pense fortement que la vérification undefined n'est pas nécessaire pour le tapuscrit : car nous devrions avoir un init var vérifié par le tapuscrit)

+1

Dans les nouvelles d'aujourd'hui, Dart obtient un support officiel pour cela : https://github.com/gbracha/nullAwareOperators/blob/master/proposal.md

Caractéristique très importante.

Peut-être une idée farfelue, mais le codegen de cette fonctionnalité pourrait être réalisé très facilement sans effets secondaires si tout le monde décidait qu'il serait acceptable de gérer la fonctionnalité avec un accès à la propriété à clé :

if (aaa?.bbb?.ccc) {}

Pourrait compiler en

if (__chain(aaa, "bbb", "ccc")) {}

Une fonction __chain devrait être émise comme __extends . La fonction __chain pourrait simplement parcourir le tableau arguments , renvoyant null lorsque le membre suivant n'est pas instanceof Object ou ne contient pas le nom du membre. Les appels de fonction peuvent être gérés en passant un tableau en tant que paramètre (et en utilisant .apply() sous les couvertures), donc ...

if (aaa?.bbb?.ccc?(1, 2, 3)) {}

Pourrait compiler en

if (__chain(aaa, "bbb", "ccc", [1, 2, 3])) {}

Cela garderait √©galement le JS g√©n√©r√© raisonnablement idiomatique, m√™me pour les longues cha√ģnes.

A peaufiner évidemment... mais peut-être qu'il y a quelque chose ici ?

Si aaa?.bbb?.ccc? renvoie la valeur de a.b.c si tous les accessoires existent et qu'il s'agit d'une fonction, alors impossible

if (aaa?.bbb?.ccc?(1, 2, 3)) {}

compiler pour

if (__chain(aaa, "bbb", "ccc")(1, 2, 3)) {}

?

@metaweta : Votre solution ne vérifie que void 0 ... cela ne va-t-il pas à l'encontre de l'objectif de la fonctionnalité ?

Et ça:

var result = one?.two?.three;

Génère :

var $a, $b, $c;
var result = $a = one, $b = $a ? $a.two : void 0, $b ? $b.three : void 0;

Je suis presque s√Ľr que cela g√®re tous les cas. Les appels de fonction n√©cessiteraient probablement une v√©rification instanceof Function .

(Léger inconvénient ici des variables locales inattendues émises ... pourrait peut-être être enveloppé dans un IIFE)

@kevinb7 : Que se passe-t-il si ccc n'est pas une fonction ? Avec le code que vous avez décrit, __chain devrait toujours renvoyer une fonction valide, sinon une TypeError serait émise.

@Back-io Lorsqu'une propri√©t√© est absente, une recherche renvoie undefined === void 0. Votre solution √©choue pour rechercher des propri√©t√©s de valeurs fausses comme une cha√ģne vide et z√©ro.

@metaweta : Non, ce n'est pas : http://jsfiddle.net/25LppbL6/

De plus, j'imagine que l'√©quipe TS n'est pas folle d'utiliser l'√©galit√© l√Ęche en raison du fait que les linters de certaines personnes mettent en garde contre cela.

@Back-io Oui, c'est le cas : http://jsfiddle.net/25LppbL6/2/

@Back-io En ce qui concerne null, je ne suis pas s√Ľr de la s√©mantique pr√©vue de a?.b. Si c'est "Si la propri√©t√© b est d√©finie, utilisez-la", alors mon code est presque correct. La seule fa√ßon d'obtenir null est si elle est affect√©e √† null, car les recherches de propri√©t√©s inexistantes renvoient undefined. Il ne parvient pas √† d√©tecter le cas o√Ļ la propri√©t√© existe mais est d√©finie sur undefined. Pour √™tre tout √† fait correct, il v√©rifierait avec Object.hasOwnProperty() au lieu de comparer √† void 0 === undefined.

Si la sémantique est "si la propriété b est véridique, utilisez-la", votre code est correct et correspond dans une certaine mesure à l'idiome JS.

Umm ... à moins que quelque chose ne me manque ... les modifications que vous avez apportées au violon me donnent encore plus raison ... var result est toujours undefined dans les 3 cas. Et je ne sais pas quel cas vous essayez de mettre en avant en étendant les prototypes primitifs ...

Je suis assez certain que le comportement de la fonctionnalité serait de court-circuiter avec void 0 au lieu de générer une erreur. (J'aime votre idée ci-dessus selon laquelle il devrait toujours renvoyer void 0 dans le cas d'un membre manquant).

Quelle est la sortie prévue de ''?.toString ?

@kevinb7 : Que se passe-t-il si ccc n'est pas une fonction ? Avec le code que vous avez décrit, __chain devrait toujours renvoyer une fonction valide, sinon une TypeError serait émise.

Bon point.

@metaweta : J'imagine que la plupart des gens s'attendraient √† une r√©f√©rence √† la fonction toString , donc je vois o√Ļ vous voulez en venir, cela se d√©compose quelque peu dans le cas o√Ļ vous acc√©dez aux membres prototypes de 0, faux, ou ''.

:+1:
Angular 2 a ajouté Elvis Operator à la syntaxe de son modèle

@metaweta :

Quelle est la sortie prévue de ''?.toString ?

Si vous vouliez dire ''?.toString() ce serait :

if ('' != null) {
  ''.toString();
}

Go√Ľter

On pourrait peut-être faire une proposition d'homme de paille pour ça

@kevinb7 ça existe déjà : http://wiki.ecmascript.org/doku.php?id=strawman :existential_operator

J'ai fait quelques tests rapides pour implémenter cela au-dessus de PropertyAccessExpression comme cas particulier, mais cela n'a pas bien fonctionné car nous avons vraiment besoin ?. soit associatif à droite (au lieu d'associatif à gauche comme . ) sinon l'émetteur devient inutilement complexe.

Il y a un commentaire de BrendenEich ici qui reflète également cela.

J'ai fait quelques tests rapides pour implémenter cela en plus de PropertyAccessExpression comme cas particulier, mais cela n'a pas bien fonctionné car nous en avons vraiment besoin. être associatif à droite (au lieu de associatif à gauche comme .) sinon l'émetteur devient inutilement complexe.

@basarat pouvez-vous s'il vous pla√ģt √©laborer sur cela? Un exemple de la diff√©rence entre l'associatif droit et l'associatif gauche ?. me serait tr√®s utile.

@zlumer

Un exemple de la différence entre associatif droit et associatif gauche ?. me serait très utile.

. est laissé associatif donc l'expression foo?.bar?.baz devient dans AST (si nous traitons ?. la même manière) :

                    // foo.bar.baz = PropertyAccessExpression
                    //   .expr foo.bar =  PropertyAccessExpression
                    //     .expr foo = Identifier
                    //     .name bar = Identifier
                    //   .name baz = Identifier

L'émission JavaScript nécessaire est

foo != null ? (ref_1 = foo.bar) != null ? ref_1.baz() : void 0 : void 0;

C'est juste plus facile de faire cette émission (surtout _récursivement_) si nous avions ce qui suit dans l'AST :

                    // foo.bar.baz = PropertySafeAccessExpression
                    //   .name foo =  Identifier
                    //   .expr bar.baz = PropertySafeAccessExpression
                    //      .expr bar = Identifier
                    //      .name baz = Identifier

Pensez simplement à _comment convertiriez-vous le premier AST en JavaScript_ et les complexités seraient plus claires. J'espère que ça t'aidera :rose:

@zlumer , pour ajouter à ce que @basarat a dit, je vais juste donner l'exemple 1 + 2 + 3 .

Lors de l'analyse, nous devons décider laquelle de ces opérations se produira en premier.

Si + est associatif à gauche, cela sera interprété comme ((1 + 2) + 3) .

Si + est associatif à droite, cela sera interprété comme (1 + (2 + 3)) .

Vous pourriez vous demander si cela ferait réellement une différence. En JavaScript, ce serait le cas ! Prenons l'exemple "hello" + 2 + 3 .

  • Associatif gauche : (("hello" + 2) + 3) => ("hello2" + 3) => "hello23"
  • Associatif √† droite¬†: ("hello" + (2 + 3)) => ("hello" + 5) => "hello5"

(Pour mémoire, JavaScript/TypeScript utilise l'associativité gauche pour l'opérateur + .)

@basarat , ma compréhension de ce que @BrendanEich a dit (et il peut me corriger si je me trompe - désolé pour le ping!) n'est _pas_ que ?. est associatif à droite, mais que la propriété des cas spéciaux de CoffeeScript accède à le droit du ?. d'être associatif à droite. Par exemple, il analysera

o.p?.q.r.s

comme

((o . p) ?. (q . (r . s))) # or something close to this

au lieu de

((((o . p) ?. q) . r) . s)

parce qu'il est plus facile à émettre.

Notre AST doit bien se prêter à une analyse sémantique saine, de sorte que notre procédure d'émission peut se permettre d'être légèrement plus complexe pour répondre à ce besoin.

@basarat @DanielRosenwasser merci pour les explications. Jusqu'√† pr√©sent, je le comprends, mais je ne suis toujours pas s√Ľr d'une chose.
L'associatif gauche ?. est assez évident et attendu :

foo?.bar?.baz

Devient (environ) :

var ref = ((ref = foo) == null) ? null : ((ref = ref.bar) == null) ? null : ref.baz;

Mais je ne comprends pas du tout comment fonctionnerait un ?. associatif √† droite. Pouvez-vous s'il vous pla√ģt donner un exemple?

Mais je ne comprends pas du tout comment ferait un droit-associatif ?. travailler. Pouvez-vous s'il vous pla√ģt fournir un exemple

@zlumer Le comportement d'exécution sera laissé associatif. Je parlais justement de l'AST comme DanielRosenwasser l'a également précisé : is not that ?. is right-associative, but that CoffeeScript special cases property accesses on the right of the ?. to be right-associative .

Notre AST doit bien se prêter à une analyse sémantique saine, de sorte que notre procédure d'émission peut se permettre d'être légèrement plus complexe pour répondre à ce besoin.

@DanielRosenwasser merci pour les commentaires :rose:

@basarat merci, d'un coup tout est devenu clair :smiley:

Similaire au commentaire de février de @basarat , je... _soupir_...

Cependant, si vous y r√©fl√©chissez, 99% des cas d'utilisation de ceci consisteront √† v√©rifier par rapport √† un pointeur nul vers un objet. Franchement, qui fait x?.b?.c quand x est un number¬†? Il n'y a tout simplement pas beaucoup de cas d'utilisation r√©els pour les cha√ģnes _longues_ lorsque nous ne parlons _pas_ d'un objet (√† l'exception peut-√™tre de string ). Pour les cha√ģnes courtes, je pense que nous pouvons vivre avec x && x.b ou x === 0 ? null : x.b .

Alors, pouvons-nous, en quelque sorte, dire que ?. ne fonctionne que sur les types d'objets¬†? Tout autre type g√©n√®re une erreur de syntaxe. Et interdire les appels de fonction dans la cha√ģne.

Ensuite, le tout se transcrit en a && a.b && a.b.c .

@schungx Et si un membre de la cha√ģne est de type "tout"¬†? Interdire compl√®tement¬†? Ou simplement laisser passer et esp√©rer le meilleur ?

Eh bien, ma suggestion? Interdire complètement. Inélégant comme l'enfer, je sais... :-)

Mais mon raisonnement :

  1. Ceci est un raccourci, donc si quelqu'un utilise any , utilisez simplement la longue main.
  2. Si quelqu'un utilise TypeScript, il l'utilise très probablement pour le support de frappe, alors j'espère qu'il n'aura pas beaucoup any autour de lui !
  3. any doit vraiment être manipulé avec précaution. Autoriser l'utilisation de ces raccourcis avec un type flexible comme any demande vraiment que des bogues se produisent. À mon avis, any devrait être aussi limité que possible. C'est un peu comme les (void *) de C -- le fait que l'on vous remette une arme nucléaire ne signifie pas que vous devez la déclencher simplement parce que vous le pouvez !

Ce serait un opérateur incroyable !! Surtout pour ES6 / ES7 / TypeScript

var error = a.b.c.d; //this would fail with error if a, b or c are null or undefined.
var current = a && a.b && a.b.c && a.b.c.d; // the current messy way to handle this
var currentBrackets = a && a['b'] && a['b']['c'] && a['b']['c']['d']; //the current messy way to handle this
var typeScript = a?.b?.c?.d; // The typescript way of handling the above mess with no errors
var typeScriptBrackets = a?['b']?['c']?['d']; //The typescript of handling the above mess with no errors

Cependant j'en propose une plus claire - pour ne pas confondre ? du un ? instructions b : c avec des instructions a?.b :

var doubleDots = a..b..c..d; //this would be ideal to understand that you assume that if any of a, b, c is null or undefined the result will be null or undefined.
var doubleDotsWithBrackets = a..['b']..['c']..['d'];

Pour la notation entre crochets, je recommande deux points au lieu d'un seul car il est cohérent avec les autres lorsque des crochets ne sont pas utilisés. Par conséquent, seul le nom de la propriété est statique ou dynamique via des crochets.

Deux points signifient que si son traitement est nul ou indéfini, arrêtez le traitement et supposez que le résultat de l'expression est nul ou indéfini. (car d serait nul ou indéfini).

Deux points le rendent plus clair, plus visible et plus spatial pour que vous compreniez ce qui se passe.

Ce n'est pas non plus jouer avec les chiffres - comme ce n'est pas le cas, par exemple

1..toString(); // works returning '1'
var x = {};
x.1 = {y: 'test' }; //fails currently
x[1] = {y: 'test' }; //works currently 
var current = x[1].y; //works
var missing= x[2].y; //throws exception
var assume= x && x[2] && x[2].y; // works but very messy

A propos des numéros deux options : Votre appel lequel peut être adopté, mais je recommande le premier pour la compatibilité avec les règles existantes !

  1. Devrait échouer comme il le fait maintenant ( x.1.y == runtime error )
var err = x..1..y; // should fail as well, since 1 is not a good property name, nor a number to call a method, since it's after x object.
  1. Devrait fonctionner car il comprend qu'il ne s'agit pas d'un numéro appelant une propriété à partir de Number.prototype
var err = x..1..y; // should work as well, resulting 'test' in this case
var err = x..2..y; // should work as well, resulting undefined in this case

Avec des noms dynamiques :

var correct1 = x..[1]..y; //would work returning 'test'
var correct2 = x..[2]..y; //would work returning undefined;

Que pensez-vous les gens?

La syntaxe PS foo?.bar et foo?['bar'] fonctionnerait aussi.

Cependant, l'utilisation à la fois de l'opérateur ? : actuel et de l'opérateur ?. peut être très déroutante sur la même ligne.

par exemple en utilisant ?. et ?['prop']

var a = { x: { y: 1 } };
var b = condition ? a?.x.?y : a?.y?.z;
var c = condition ? a?['x']?['y'] : a?['y']?['z'];

par opposition aux doubles points .. et ..['prop']

var a = { x: { y: 1 } };
var b = condition ? a..x..y : a..y..z;
var c = condition ? a..['x']..['y'] : a..['y']..['z'];
Laquelle vous semble la plus claire ?

Très intéressant. :+1:

√Ä mon humble avis, deux points seront plus d√©routants. Il existe des langages o√Ļ deux points repr√©sentent une plage (par exemple 1..4 ) et TypeScript peut ajouter cette fonctionnalit√© √† l'avenir.

Un point d'interrogation a également le sens sémantique d'incertitude ou de conditionnel et deux points n'ont pas le même sens.

@schungx Assez juste, mais cela aiderait pour les possibilités étranges comme celle-ci : a?['b'] ou ce a?() .

+1 ?

a?['b'] et a?() se comportent bien dans coffeescript, et ils me paraissent bien.

Mais encore une fois, je pourrais juste être aveugle au coffeescript.

+1 Ruby vient d'implémenter l'opérateur existentiel https://twitter.com/mikepack_/status/657229703443451904. Typescript en a également besoin, quelle que soit la syntaxe spécifique.

Ce serait rendre le code plus propre ūüĎć

+1 Besoin de ça !

S'il vous pla√ģt, impl√©mentez?. op√©rateur, comme le fait C#

+1 ça faisait longtemps que ça me manquait

+1
si moche à écrire : uneVariable && uneVariable.unMembre
quand vous pourriez écrire : someVariable?.someMember

+1, ce serait génial.... (fonctionnalité la plus recherchée pour moi)

+1, c'est une bonne idée !
Seulement, si l'objet est compliqué, l'expression sera pleine de ?. après chaque propriété (var result=myValue?.a?.b?.c?.d?.e;) quand j'ai besoin de recevoir une valeur de la dernière (var result=?myValue.abcde;).

+1 - C'est sans doute l'une des plus grandes fonctionnalités de CoffeeScript et c'est de loin la fonctionnalité TypeScript la plus souhaitée par mon équipe après avoir converti une grande partie de notre code de CS en TS.

+1 cependant, c'est trop complexe:

var x = { y: { z: null, q: undefined } };
var z: x|y|z = x?.y?.z;

J'aime ça:

var x = { y: { z: null, q: undefined } };
var z: z|void = x?.y?.z;

Le type x?.y?.z est toujours le type du champ z . Bien s√Ľr, le type doit √™tre nullable et la valeur r√©elle peut √™tre null. S'il n'est pas nul, il doit √™tre du type du champ z .

+1 Cela irait bien avec la vision de Typescript de faciliter le développement de projets JS complexes à grande échelle.

Des mises √† jour √† ce sujet¬†? S'agit-il d'un cas o√Ļ la communaut√© vote pour cette fonctionnalit√© pour qu'elle soit prise en compte¬†? Ou cela a-t-il √©t√© envisag√©, mais il y a des d√©fis d'ing√©nierie ?

Aucune mise à jour jusqu'à présent car l'introduction d'une nouvelle syntaxe au niveau de l'expression est dangereuse sans une sorte de proposition du comité ECMAScript.

Voir https://github.com/Microsoft/TypeScript/issues/16#issuecomment -57645069.

Voici une discussion plus actuelle sur les opérateurs existentiels (beaucoup de réflexions, mais ne ressemble pas à beaucoup d'action):

o√Ļ dois-je √©crire "+1" pour aider √† l'amener √† ES¬†?

@msklvsk ESDiscuter

Fermant ceci pour l'instant. Puisqu'il n'y a rien de sp√©cifique √† TypeScript qui n√©cessiterait cela au niveau de l'expression, ce genre de changement important d'op√©rateur devrait se produire au comit√© de sp√©cification ES plut√īt qu'ici.

Le d√©clencheur g√©n√©ral pour r√©√©valuer cela serait une proposition ES concr√®te atteignant l'√©tape suivante, ou un consensus g√©n√©ral du comit√© ES selon lequel cette fonctionnalit√© ne se produirait pas avant longtemps (afin que nous puissions d√©finir notre propre s√©mantique et √™tre raisonnablement s√Ľrs qu'ils "gagneraient").

la vie craint

Suppression autonome :+1:s. Veuillez utiliser la fonctionnalité de réactions GitHub ou envoyer des fleurs et des bonbons à votre représentant TC39 le plus proche.

Une fois que je m'y suis habitué dans coffeescript et Swift, il n'y a pas de retour en arrière. TS est mort pour moi tel qu'il est actuellement.

@algesten Je peux √™tre d'accord sur swift si l'on consid√®re le langage lui-m√™me, pas s√Ľr du support √† long terme coffescript (j'utilise CoffeScript dans des projets de production). Nous pouvons convenir d'√™tre s√Ľrs des tendances de l'analyse linguistique en juin 2016 comme celle -ci o√Ļ nous pouvons clairement voir ce qui se passe pour coffescript r√©cemment, tandis que TypeScript a connu la croissance la plus rapide au cours des derni√®res ann√©es¬†:

TypeScript¬†: en dehors de Go ou de Swift, le langage qui conna√ģt la croissance la plus rapide ces derni√®res ann√©es est TypeScript. Le sur-ensemble JavaScript soutenu par Microsoft et la fondation Angular 2 ont r√©alis√© des gains significatifs pour le deuxi√®me trimestre cons√©cutif, passant du n ¬į 31 au n ¬į 26. Il s'agissait du plus grand changement dans toutes les langues du Top 30 et du deuxi√®me saut le plus important dans l'ensemble (Standard ML, 7 places). Au n ¬į 26, en fait, TypeScript est maintenant √† √©galit√© avec Erlang, une place derri√®re Powershell et quatre derri√®re CoffeeScript, qui est juste en dehors du Top 20. La question √† laquelle le langage est confront√© n'est pas de savoir s'il peut se d√©velopper, mais s'il a l'√©lan pour percer le Top 20 dans les deux √† trois prochains trimestres, d√©passant les go√Ľts de CoffeeScript et Lua dans le processus.

Jusqu'en 2014, les tendances coffescript étaient plus que positives comme vous pouvez le voir ici , c'est à ce moment que le déclin a commencé.

Avec la nouvelle v√©rification strict null (undefined) de Typescript 2.0, c'est un must, car sinon vous ne pouvez pas utiliser le cha√ģnage de fonctions !

Cela devrait être dans la prochaine version d'ECMAScript. Considérant que cela serait encore plus utile dans le JavaScript vanille que TypeScript et considérant que l'implémentation serait naturellement une vérification pour undefined ou null par opposition à une vérification de la vérité, il devrait être trivial pour TC39 d'ajouter.

L'implémentation simple et qui serait idiomatique en JavaScript, consisterait simplement à court-circuiter lors de la rencontre de null ou undefined, et de renvoyer undefined.

@bterlson est-ce que cela a du sens? Quelles sont les chances qu'une telle proposition soit acceptée ?

L'un des grands avantages du tapuscrit est que "l'avenir vous est donné aujourd'hui". C'est l'une des fonctionnalités qui m'a surpris et qui ne sont pas déjà là.

J'esp√®re qu'il sera ajout√© bient√īt car le cha√ģnage de fonctions est un idiome populaire et la v√©rification stricte de null ne fonctionnera plus √† moins que le ?. l'op√©rateur est ajout√©.

TS 2 merveilleuse vérification nulle en a fait un incontournable!

En lisant ce fil, je suis un peu surpris de voir que cela n'attire pas plus l'attention des responsables.

Dans un monde id√©al, TypeScript devrait ouvrir la voie √† ES et non l'inverse. S√©rieusement, o√Ļ en serait TypeScript maintenant si l'√©quipe TS aurait toujours attendu qu'ESx propose et finalise une fonctionnalit√© ou une syntaxe ?

Cette syntaxe est vraiment un "must have", comme d'autres l'ont soulign√©. Il a m√™me re√ßu de bonnes propositions dans ce fil jusqu'√† pr√©sent. Je pense que la mise en Ňďuvre doit correspondre √† ces attentes.

  • En g√©n√©ral, une expression a?.b devrait √™tre valide au moment de la compilation si et seulement si a.b est valide.
  • Il ne doit √©valuer chaque expression de la cha√ģne qu'une seule fois.
  • Il doit s'agir d'un court-circuit.
  • Si l'ex√©cution atteint une expression interm√©diaire avec la null ou undefined , cette valeur doit √™tre la valeur de retour.

Selon vous, quelles sont les parties qui peuvent conduire à des désaccords lorsque ES le précisera ?

Pour a?.b je ne vois aucun conflit avec la syntaxe existante (et future ?). Si l'analyseur trouve le jeton ?. , il peut le traiter comme un "op√©rateur de navigation s√Ľr" (avec des attentes telles que d√©crites par @cervengoc).

Les conflits de syntaxe surviennent uniquement lorsque vous autorisez a?(b) et a?[b] , car ceux-ci pourraient √©galement √™tre interpr√©t√©s comme le d√©but d'une expression d'op√©rateur ternaire ?: . Mais pour commencer, je pense que ceux-ci pourraient √™tre mis de c√īt√© et ne supporter que la syntaxe a?.b ferait d√©j√† plaisir √† beaucoup de d√©veloppeurs¬†!

Dans un monde idéal, TypeScript devrait ouvrir la voie à ES et non l'inverse.

En termes de syntaxe au niveau de l'expression, nous ne sommes absolument pas d'accord. Il y a un comité qui dirige une norme pour une raison - pas pour que des actions ponctuelles d'un joueur puissent décider unilatéralement de l'avenir de JavaScript.

Cette syntaxe est vraiment un "must have", comme d'autres l'ont souligné.

Si c'est un must pour TypeScript, c'est aussi un must pour JavaScript ! Encore une fois, faites part de vos préoccupations au comité ECMAScript .

Selon vous, quelles sont les parties qui peuvent conduire à des désaccords lorsque ES le précisera ?

Au minimum, je pense qu'il y aura un désaccord quant à savoir si la syntaxe court-circuite à null ou undefined lors de la rencontre de ces valeurs, ou toujours court-circuite à undefined . Il va également y avoir des controverses sur la prise en charge ou non d'une certaine forme de syntaxe entre crochets. Il y a aussi la question de savoir quel est le comportement de a?.b.c . Il y a aussi la question de ?. vs .? vs a.b? . Il y a la question de savoir quel est l'effet de ceci sur l'opérateur delete .

Le fil ES DISCuss √† ce sujet compte plus de 100 commentaires. L'ambigu√Įt√© ne manque pas ! Il est facile de regarder un exemple isol√©ment et de penser qu'il ne peut pas y avoir des tonnes de cas particuliers. Il y a. C'est probablement pourquoi personne n'a encore d√©fendu cela au TC39 et _aussi_ pourquoi nous ne nous pr√©cipitons pas pour ajouter une fonctionnalit√© qui a beaucoup d'ambigu√Įt√© sur la fa√ßon dont elle devrait se comporter.

Je m'excuse, je n'ai pas lu le fil mentionn√©, je vais certainement y jeter un Ňďil pour en savoir plus.

Nous voyons cela un peu diff√©remment. √Ä propos du comit√©, √† mon avis honn√™te, c'est l'une des principales raisons pour lesquelles JavaScript ne sera jamais _bon_. Juste pour un exemple, bon nombre des logiciels les plus r√©ussis que j'ai vus (comme Total Commander ou IrfanView) r√©ussissent parce qu'ils sont maintenus et con√ßus par UNE personne, et non par un *comit√©". Bien s√Ľr, ce n'est pas compl√®tement Mais je suis presque s√Ľr que si, par exemple, vous seul aviez con√ßu l'ES6 complet, alors le monde serait un meilleur endroit maintenant.

De plus, les ambigu√Įt√©s que vous avez mentionn√©es sont √† 99% _th√©oriques_ et en quelque sorte non pertinentes du c√īt√© du d√©veloppeur. Qui se soucierait de ce qu'il renvoie, null ou undefined¬†? Choisissez-en un et nous l'utiliserons comme √ßa.

Dans l'ensemble, vous et ce comit√© √™tes d'un c√īt√© diff√©rent de la plupart d'entre nous, et les choses de ce c√īt√©-l√† sont g√©n√©ralement plus complexes qu'elles ne le sont r√©ellement. Et cela peut conduire √† une certaine contre-productivit√©, c'est le moins qu'on puisse dire. Ne le prenez pas personnellement, mais selon mon exp√©rience en g√©n√©ral, certaines personnes feraient mieux de sortir plus souvent de la salle de conf√©rence et de jeter un Ňďil √† du code.

Bien s√Ľr, ne vous offensez pas, ne prenez rien personnellement, j'ai un immense respect pour vous et toute l'√©quipe TS, car vous avez r√©volutionn√© le d√©veloppement c√īt√© client de nombreux d√©veloppeurs, y compris moi-m√™me, et merci pour tout votre travail. Nous sommes juste un peu d√©√ßus par celui-ci, je suppose.

Une derni√®re pens√©e. J'ai parcouru le fil ES mentionn√©, et une chose est tout √† fait s√Ľre : ils le compliquent trop. Ils veulent concevoir quelque chose qui soit bon pour chaque sc√©nario.

Personnellement, je serais entièrement satisfait et heureux avec un opérateur d'accès conditionnel aux membres . Vous n'avez pas besoin d'invocation conditionnelle, de signature d'index conditionnel, vous n'avez pas besoin de prendre en charge tous les scénarios fantaisistes qui sont du code JS valide. C'est tout. Mais au lieu de cela, ils resteront probablement assis là et discuteront de la façon de tout faire en même temps, ce qui est un excellent plan, mais nous n'aurons rien à la fin de la journée.

Dans l'ensemble, vous et ce comit√© √™tes d'un c√īt√© diff√©rent de la plupart d'entre nous, et les choses de ce c√īt√©-l√† sont g√©n√©ralement plus complexes qu'elles ne le sont r√©ellement.

Je ne pense pas que vous refl√©tiez avec pr√©cision le v√©ritable statut de Ryan ou de TC39. Ryan et l'√©quipe TypeScript ont d√©fini des objectifs de conception tr√®s clairs pour TypeScript. L'un des objectifs originaux et toujours tr√®s actuels est que TypeScript est un sur-ensemble de JavaScript. Pas la langue que les gens aimeraient que ce soit (par exemple Dart, Haxe). En ce qui concerne la syntaxe, l'√©quipe TypeScript a appris √† ses d√©pens le co√Ľt de sa pr√©-invention (par exemple, les modules). Nous nous dirigeons aussi t√™te baiss√©e vers un d√©fi avec les membres priv√©s des classes, o√Ļ la syntaxe ES propos√©e est totalement incompatible avec la syntaxe utilis√©e par TypeScript. Pourquoi? Parce que ce qui peut sembler simple √† premi√®re vue est impossible √† r√©aliser compte tenu des d√©fis d'ex√©cution d'un langage.

TC39 a "sauvé" JavaScript à mon avis. ES4 a été abandonné, non pas parce qu'il manquait de bonnes idées innovantes, mais parce qu'il casserait Internet. TC39 s'est mis en forme, ils ont partagé et ont été totalement ouverts dans leurs discussions et la façon dont ils prennent des décisions et nous ont livré ES2015, qui ressemble beaucoup à ES4, mais n'a pas cassé Internet. Il est étonnant que nous ayons essentiellement des temps d'exécution JavaScript qui exécutent parfaitement du code d'il y a 10 ans, mais prennent en charge de nombreuses améliorations significatives du langage. ES2016 était l'accalmie avant la tempête. ES2017 a une quantité "raisonnable" de fonctionnalités et de changements et un processus de gouvernance clair qui va dans la bonne direction.

Donc, √™tre du "c√īt√© diff√©rent" des choses a clairement fonctionn√©, √† mon avis. Ce qui bat l'opportunit√© des fonctionnalit√©s "indispensables".

@kitsonk Je ne voulais pas dire "c√īt√© diff√©rent" n√©gativement, et surtout je ne voulais pas d√©grader le travail ce qui a √©t√© mis dans TypeScript ou ES6. De plus, la meilleure chose dans TypeScript IMO est qu'il avait vraiment et a un objectif de conception clair, et il est bien prot√©g√© contre les ravages comme beaucoup d'autres choses open source.

Je voulais juste dire que cette fonctionnalit√© m√™me est un exemple clair de l'endroit o√Ļ un groupe de g√©nies finira par trop r√©fl√©chir et trop compliquer les choses, au lieu d'aller simplement de la mani√®re la plus simple, et accepter certaines limitations comme ne pas prendre en charge les invocations ou les signatures d'index, etc. Quelqu'un dans ce forum a m√™me sugg√©r√© d'utiliser cette syntaxe dans les devoirs, ce qui est un peu fou. Je pense toujours que ce ph√©nom√®ne est contre-productif en ce sens.

Je comprends que de votre c√īt√© c'est une douleur que par exemple les membres priv√©s soient devenus incompatibles avec le concept final de l'ES6. Mais d'un autre c√īt√©, nous l'avions. Bien avant l'ES6. Et c'est le point principal de notre c√īt√©. En gros, nous ne nous soucions pas de savoir comment vous parvenez √† √©mettre le code appropri√© pour cela, nous l'utilisons simplement avec plaisir. Idem avec les modules, et tout. Nous (ou du moins je) n'ai pas vu ces douleurs dont vous parlez, nous avons toujours √©t√© satisfaits des membres priv√©s ou des modules.

Cette fonctionnalit√© particuli√®re est dans CoffeScript comme je l'ai lu √† ce sujet. Pourquoi nous, simples d√©veloppeurs devons-nous toujours faire des compromis lors du choix d'une plateforme/librairie/plugin, etc. ? Je veux dire toujours . C'est un peu ennuyeux. Nous avons ici un langage formidable, qui a un grand potentiel, qui laisse compl√®tement tous les autres participants derri√®re (y compris ES¬†!), et qui a r√©volutionn√© avec succ√®s une grande partie du d√©veloppement c√īt√© client, et en ce qui concerne cette fonctionnalit√© "simple" ( Je veux dire au moins la partie acc√®s aux membres), nous entendons dire qu'elle ne sera pas mise en Ňďuvre tant que ES ne s'y sera pas engag√©.

Je voulais informer rapidement les gens que cette fonctionnalité est passée de l'étape 0 à l'étape 1 lors de la réunion TC39 d'aujourd'hui.

Commit pertinent : https://github.com/tc39/proposals/commit/cb447642290a55398d483f5b55fb7f973273c75d
Ordre du jour de la réunion : https://github.com/tc39/agendas/blob/master/2017/01.md

Wow! c'est énorme!

Vaut également un lien vers https://github.com/claudepache/es-optional-chaining

Quelques "surprises" que je vois ici (ne disant pas que je ne suis pas d'accord, juste des choses que nous aurions probablement faites diff√©remment si nous l'avions fait plus t√īt):

  • null n'est pas produit √† partir d'une expression a?.b¬†: lorsque a est null , cela produit undefined la place
  • ~Propagation en points cha√ģn√©s : a?.b.c.d ne sera pas lanc√© si les propri√©t√©s b et c sont undefined ~ Ryan ne peut pas lire
  • ~Propagation en pr√©sence de parenth√®ses¬†: m√™me (a?.b).c ne sera pas lanc√© si b n'est pas d√©fini~ Ryan ne sait pas lire
  • ~La propagation se produit m√™me sur les appels de m√©thode : a?.b.c().d renverra undefined si l'invocation c renvoie null ~ Ryan ne sait pas lire
  • L'op√©rateur delete est pris en charge
  • La syntaxe des parenth√®ses a?.[x] est prise en charge
  • La syntaxe d'appel de fonction func?.(...args) est prise en charge, m√™me pour les appels sans m√©thode (!)

Je m'attends à voir des changements dans ces domaines d'ici l'étape 2.

Je pense que coffeescript a bien compris.

a?.bc est lancé si b n'est pas défini.

a?() et a?[0] sont tous les deux bons.

  • Propagation en points cha√ģn√©s¬†: a?.bcd ne lancera pas si les propri√©t√©s b et c ne sont pas d√©finies
  • Propagation en pr√©sence de parenth√®ses : pair (a?.b).c ne lancera pas si b est ind√©fini
  • La propagation se produit m√™me sur les appels de m√©thode¬†: a?.bc().d renverra undefined si l'invocation c renvoie null

Ces points ne me semblent pas exacts. De la proposition :

a?.b.c().d      // undefined if a is null/undefined, a.b.c().d otherwise.
                // NB: If a is not null/undefined, and a.b is nevertheless undefined,
                //     short-circuiting does *not* apply

Wow, j'ai totalement mal lu. Tu as raison. Mise à jour

@algesten de la proposition originale :

a?.()

b?.[0]

sucré. l'opérateur peut en quelque sorte être comme ?. alors.

Il y a une conversation supplémentaire en cours ici : https://github.com/estree/estree/issues/146

Une citation qui pourrait bien s'appliquer : ¬ę Rendre les choses simples faciles et les choses difficiles possibles ¬Ľ. Ainsi peut-√™tre, prenez bien en charge les cas les plus courants, tout en ignorant (au moins initialement) les cas compliqu√©s/rares, alors qu'ils sont toujours autoris√©s √† √™tre "faits manuellement" avec une syntaxe plus longue (existante).

Juste mes deux cents

let a = b?.c?.d?.e;

pour:

let a;
try{
   a = b.c.d.e;
}catch(e){
   a = undefined;
}

@cedvdb sémantique totalement différente - les exceptions lancées dans les getters ne doivent pas provoquer de fusion

@RyanCavanaugh ouais .. Je n'y ai pas réfléchi.

Est-ce sur le radar pour la mise en Ňďuvre maintenant, ou l'√©quipe TS attendra-t-elle que la proposition ES aille plus loin¬†?

C'est sur notre courte liste; nous avons encore quelques questions/préoccupations, mais vous devriez voir du mouvement à ce sujet dans le mois à venir.

Je ne sais pas d'o√Ļ vient le commentaire de @mhegazy - le nombre de questions ouvertes sur la proposition TC39 est trop important pour que nous puissions faire un travail significatif ici. Plus pr√©cis√©ment, les questions sur la mani√®re dont null et undefined interagissent et sur la syntaxe r√©ellement prise en charge doivent √™tre trait√©es en premier. L'√©tape 2 est un strict minimum absolu et nous pr√©f√©rerions l'√©tape 3 compte tenu de l'impact sur le comportement d'ex√©cution.

est-ce que ce code fonctionne simplement?

a == undefined ? expression : undefined

expression signifie ax, a[x], a(x), delete pourrait également être généré ici

alors a?.b?.[c]?.(d) générera

a == undefined ? (a.b == undefined ? (a.b[c] == undefined ? a.b[c](d) : undefined) : undefined) : undefined

semble passer par toute la règle de RyanCavanaugh


si déteste l'opérateur == , il pourrait aussi être a === undefined || a === null

@zh99998 vous _devez_ d√©tester == parce que '' et 0 sont √©galement assimil√©s. On pr√©tend presque que le comportement d'ex√©cution devrait √™tre une sorte de contr√īle sur (typeof value === 'object' || typeof value === 'function' || typeof value === 'symbol') && value !== null , ce qui devient maintenant assez complexe.

Comme @RyanCavanaugh l' a dit, il est peu probable qu'il progresse tant que la proposition du TC39 n'atteindra pas au moins l'étape 2 ou 3.

Je vois que == n'est égal qu'à null et undefined comme
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Equality_comparisons_and_sameness

et test réussi dans la console chrome :

'' == undefined
false
0 == undefined
false

@kitsonk undefined ne contraint qu'à null et vice versa. Aucune autre valeur ne contraint à undefined ou à null.

Vous semblez confondre avec de fausses valeurs. 0 et "" sont en effet faux, mais ne seront jamais contraints à null ni à undefined.

== implique la coercition. null == 0 est faux car rien sauf undefined ne peut forcer à null. Il en va de même pour undefined == 0 .

Un autre exemple pourrait être

    if(!NaN) console.log("NaN is falsy") // NaN is falsy
    if(false == NaN) console.log("NaN coerces to false")
   else console.log("NaN doesn't coerce to false");// NaN doesn't coerce

Vous obtenez l'image.

Je vois beaucoup de tentatives d'utilisation d'op√©rateurs ternaires, mais toute impl√©mentation faisant r√©f√©rence √† la m√™me propri√©t√© plusieurs fois peut entra√ģner des effets secondaires inattendus.

Heureusement, JavaScript a des IIFE, vous pouvez donc stocker le résultat d'un accesseur dans un paramètre de fonction, vous y référer autant que vous le souhaitez et ne jamais l'évaluer plus d'une fois. Dans mon exemple ci-dessous, je crée un lambda coalesce qui peut être appelé plusieurs fois à la place d'une expression contenant des opérateurs ?. .

Une chose dont les implémenteurs de langage devraient se préoccuper est les appels de tableau et de fonction au milieu d'une expression. Je pense que le compilateur pourrait gérer la détection de ces situations et simplement ajouter ces expressions à la fin de l'appel coalesce.

const coalesce = (x: any, y: string) => x == null ? null : x[y];

const x = {
    y: {
        z: "Hello, World!!!"
    },
    f: () => "Foo!",
    a: ["Array!"]
};

// x?.y?.z
const value1 = coalesce(coalesce(x, 'y'), 'z');

// x?.f()
const value2 = coalesce(x, 'f')()

// x?.a[0]
const value3 = coalesce(x, 'a')[0]

Notez qu'il n'y a pas besoin d'un nom global réel "coalesce". Ce code peut être directement intégré dans n'importe quelle expression. Cela pourrait cependant réduire le ballonnement en lui donnant un nom.

Je ne suis pas trop concerné par la syntaxe utilisée pour l'opérateur ou si les implémenteurs du langage veulent attendre un standard. Je pensais juste montrer une autre approche.

Cela soulève également la nécessité d'un opérateur ?? . En C#, cela remplace toute expression null par ce qui se trouve à droite.

string x = null ?? "Hello";
````

In JavaScript, it is more idiomatic to use `||` to replace "falsey" values with the value on the right. 

```javascript
var x = null || "Hello";

Malheureusement, la véracité capture trop de cas extrêmes ( 0 , false , etc.). En travaillant avec un opérateur null coalesce ( ?. ), vous voudriez quelque chose de spécifique à null -ness.

const x = { y: "" };
const result1 = x?.y || "default";  // I'd expect "default"
const result2 = x?.y ?? "default";  // I'd expect "" 

@jehugaleahsa , dans votre exemple avec coalesce, il devrait y avoir un moyen d'empêcher les appels de fonction et l'accès des membres de se produire si la vérification avant retournait null. Dans l'exemple x?.f(), f ne doit pas être appelé si x est nul.

@bschlenk Je ne pense pas être d'accord. Je pense que cela devrait échouer avec un message comme null is not a function , mais ce n'est pas à moi, je suppose.

La r√©cente vague de commentaires d√©taillant les moyens possibles de mettre en Ňďuvre l'op√©rateur est un peu bizarre.
La mise en Ňďuvre est probablement un probl√®me r√©solu.

Si vous êtes intéressé, il y a la bibliothèque idx , qui ressemble beaucoup au comportement de l'opérateur ?. , bien qu'elle ignore également de nombreux détails de l'opérateur prévu. Quoi qu'il en soit, leurs spécifications pour la sortie de compilation pourraient intéresser tous ceux qui s'interrogent sur la manière dont ces éléments pourraient être implémentés.

TS pourrait sortir quelque chose comme ça ou il pourrait sortir quelque chose de complètement différent, mais je ne pense pas que ce soit ce que nous attendons ici. Il a été dit à plusieurs reprises ici que TS n'obtiendrait pas l'opérateur tant que la proposition ES n'évoluerait pas dans un sens ou dans l'autre.

C'est la sémantique qui a encore quelques inconnues, listées ici et ici .

Soyez assur√© que nous mettrons cela en Ňďuvre correctement et que nous n'avons pas besoin de 100 autres commentaires ici pour comprendre ce que font || et ? ... : ... . Comme @noppa l'a not√©, nous attendons juste la finalisation de la sp√©cification ES.

https://github.com/babel/babel/pull/5813 (accompagnant babylon PR ) vient d'√™tre fusionn√© avec Babel's preset-stage-1 . La sp√©cification est toujours au stade 1, bien s√Ľr, mais cela aidera √† la faire avancer.

Peut-être que je me trompe, mais je n'ai pas vu de lien évident vers la proposition tc39 dans ce fil, alors la voici pour les futurs lecteurs : https://github.com/tc39/proposal-optional-chaining

Pour info le cha√ģnage optionnel sera au TC39 la semaine prochaine https://github.com/tc39/agendas/blob/master/2017/07.md

@jehugaleahsa Je pense que vous avez raison et je présenterai ?? au TC39 la semaine prochaine. Vous pouvez suivre la proposition ici : https://github.com/gisenberg/proposal-nullary-coalescing

Je vois que le cha√ģnage optionnel √©tait couvert au TC39... Quel a √©t√© le verdict ?
J'esp√®re que c'√©tait suffisant pour faire avancer cela dans Typescript ūüėČ

@markwhitfeld D'après le résumé des notes :
Op√©rateurs de cha√ģnage optionnels : reste √† l'√©tape 1, reviendra plus tard avec des d√©finitions plus claires pour diverses options et des r√©ponses aux commentaires

Notes complètes ici : https://github.com/rwaldron/tc39-notes/blob/master/es8/2017-07/jul-27.md#13iia -optional-chaining-operator

Il y a encore des questions ouvertes sur la fa√ßon dont l'op√©rateur doit se comporter, il semble donc qu'il ne soit pas encore dans un √©tat o√Ļ il peut √™tre ajout√© √† TypeScript.

D'apr√®s ces notes, il semble que le comit√© n'ait aucune id√©e du fonctionnement des options pr√©sent√©es, j'aurais pens√© qu'ils auraient pris connaissance des propositions dont ils pr√©voyaient de discuter, avant d'en discuter. Je suppose que cela va prendre un peu plus de temps jusqu'√† ce que je puisse activer les contr√īles nuls stricts.

J'espère vraiment qu'ils opteront pour l'option 2/4 (qui est de toute façon l'état actuel de la proposition).

15 juillet 2014 - 4 septembre 2017, rien encore

@frankfvb vous n'avez clairement pas lu le problème.

Il y a eu beaucoup de discussions qui ont conduit l'√©quipe principale √† croire qu'il serait imprudent de mettre en Ňďuvre √† ce stade jusqu'√† ce que de nouveaux progr√®s soient r√©alis√©s sur la proposition ECMAScript, ce qui aurait un impact direct sur la fonctionnalit√© de cette fonctionnalit√© dans TypeScript.

Depuis la derni√®re r√©union du comit√© des normes ECMAScript, la proposition reste √† l'√©tape 1 car elle pose des questions tr√®s fondamentales sur la mani√®re dont elle serait mise en Ňďuvre. Bien qu'il ne s'agisse pas d'une r√®gle absolue, TypeScript n'impl√©mentera que les propositions de l'√©tape 3. Il impl√©mente parfois les propositions de l'√©tape 2 s'ils pensent que cela est d'une importance critique et que l'utilisation potentielle dans TypeScript entra√ģne l'√©volution de la norme.

Je ne sais pas comment des gens plus clairs peuvent être à ce sujet.

Comme je l'ai dit plus t√īt , cela fait partie de notre liste restreinte. nous attendons que TC39 parvienne √† une sorte de consensus sur la s√©mantique de l'op√©rateur. nous d√©testerions le publier et casser ensuite les utilisateurs.

Ce n'est pas le fil pour ressasser la discussion TC39

Si vous voulez peser dans la proposition, allez la commenter à l'endroit approprié . J'ai aussi des opinions, mais les déposer dans ce fil ne va rien faire.

J'ai cr√©√© quelque chose de simple qui r√©pond √† mes besoins actuels. Cela ne fonctionnera que sur une cha√ģne o√Ļ chaque lien est un nom de propri√©t√©, donc l'acc√®s √† un √©l√©ment dans un tableau (par exemple) n'est pas pris en charge.

Implémentation d'un opérateur Elvis très simple dans TypeScript

De plus, si vous avez lodash/underscore, vous pouvez déjà utiliser _.get(Book, 'author.name.firstName') qui fera ce que cela veut

Edit : Apparemment, c'est un mauvais conseil en raison de problèmes de type avec la méthode _.get() . Voir commentaire ci-dessous

@tolgaek , _.get a de mauvaises frappes, même avec ces meilleures frappes ( pas encore fusionnées , à cause des auteurs) le dactylographie ne peut certainement déduire le type de résultat que si la profondeur de l'objet est de 1, dans tous les autres cas c'est any et doit être vérifié au moment de l'exécution

D'un autre c√īt√©, avec l'op√©rateur elvis, le script peut √™tre en mesure de d√©duire le type de r√©sultat dans des objets de n'importe quelle profondeur, c'est pourquoi j'attends avec impatience l'op√©rateur elvis

oh je vois, je ne savais pas qu'il y avait un problème de frappe. Merci @BjornMelgaard

@mhegazy cette fonctionnalité ne peut-elle pas être implémentée en premier et marquée comme fonctionnalité expérimentale ? Je pense que les gens ne devraient pas avoir de problème si les spécifications sont modifiées dans la fonctionnalité expérimentale.

Elvis n'est pas amusé à attendre aussi longtemps.

Il a atterri √† Babel7. Tapuscrit, nous sommes lents.. Quelqu'un s'il vous pla√ģt, faites que cela se produise.
:)

@gs-akhan le plugin Babel implémente une ancienne version de la proposition d'il y a quelques mois. Il y a eu des changements dans la proposition depuis lors (y compris un changement significatif dans la façon dont l'opérateur est analysé), et il y aura probablement plus de changements avant que la fonctionnalité n'atteigne l'étape 2 (sans parler de l'étape 3), donc tout code écrit avec le babel actuel plugin pourrait se casser lorsque la fonctionnalité réelle est publiée. Babel implémente intentionnellement les fonctionnalités proposées avant qu'elles ne soient stables afin que les auteurs de spécifications et les autres parties intéressées puissent essayer la fonctionnalité telle que proposée. Ce n'est pas parce que Babel a implémenté une fonctionnalité qu'elle peut être implémentée d'une manière qui ne nécessitera pas de modifications majeures à l'avenir.

@alangpierce Cela a du sens. Merci

Je comprends que c'est un opérateur vraiment, vraiment sympa, mais le fait qu'il soit disponible avant que ses règles ne soient aplanies est une arme de pied et nous n'allons pas le faire. Le comportement d'exécution de l'opérateur est toujours en évolution ; si vous écrivez du code aujourd'hui, il pourrait cesser de fonctionner demain d'une manière qui n'est pas immédiatement apparente - peut-être des plantages rares, peut-être une corruption de données, qui sait ? Un peu de patience maintenant vous évitera beaucoup de douleur dans quelques mois.

Je commence à penser que ce ticket devrait être verrouillé (et non fermé) jusqu'à ce que la spécification soit prête.

Quand la spécification sera-t-elle prête ?

@oliverjanik Le projet de sp√©cification actuel peut √™tre trouv√© ici . Il y a un point √† l'ordre du jour pour faire avancer la proposition √† l'√©tape 2 lors de la prochaine r√©union du TC39 (26/09-28/09). Je pr√©senterai ces diapositives √† ce moment-l√†. Pour les personnes qui souhaitent examiner plus t√īt et fournir des commentaires, veuillez signaler les probl√®mes sur le d√©p√īt de la proposition .

Merci beaucoup @gisenberg d'avoir défendu ce problème pour nous ! Je pensais créer un diaporama récapitulatif pour aider à clarifier les options autour de l'opérateur qui pourraient être utilisées lors de la réunion TC39 afin d'éviter toute confusion, mais vous l'avez déjà fait. Super travail!
Peut-être qu'une autre chose qui pourrait être bénéfique pour la conversation TC39 (et le jeu de diapositives) est de regarder la sémantique et la syntaxe de l'opérateur dans d'autres langues. Bien que d'autres langages ne doivent pas nécessairement dicter comment cela devrait fonctionner en Javascript, il serait utile de garder l'opérateur similaire à celui des autres langages afin d'éviter toute confusion.
Bon courage pour la semaine prochaine !!!

D√©sol√© d'√™tre un peu hors sujet une fois de plus, mais j'ai pens√© que certaines personnes ici pourraient trouver int√©ressant que dans Flow, il soit maintenant possible d'ajouter des d√©finitions de type quelque peu fonctionnelles pour des fonctions getter s√Ľres comme _.get .

Exemple : flowtype.org/try

Ce n'est pas le plus beau morceau de code de tous les temps et il ne fait pas correctement la distinction entre null et undefined, mais à part cela, il semble fonctionner assez bien.

AFAIK, la seule chose qui manque à TS pour qu'il fasse la même chose est quelque chose comme ça $NonMaybeType .
Non pas que cela supprimerait le besoin de cet op√©rateur, bien s√Ľr, j'ai juste pens√© que c'√©tait cool.

Cela n'a pas atteint l'étape 2 lors de la dernière réunion du TC39 en raison de préoccupations concernant la cohérence syntaxique concernant l'accès entre parenthèses, points et appels et le comportement sémantique (prévisibilité autour des effets secondaires des expressions à droite d'un undefined / null -opérande évalué) ainsi que des questions ouvertes sur le type d'expressions autorisées à ne pas être utilisées (par exemple, x.?b() lorsque x.b est un number )

(votez ūüéČ sur ce commentaire pour jeter des fruits pourris)

Merci de nous en informer. Quelle déception. Peut-être que la portée doit être réduite pour que ce soit plus simple mais toujours utile?

Peut-être que la portée doit être réduite pour que ce soit plus simple mais toujours utile?

C'est le d√©fi auquel TC39 est confront√©, qui, bien que nul, je dois admettre que je suis heureux que les gens traversent cela. Il est vraiment difficile pour eux d'introduire une syntaxe de niveau assez complexe et en fait, dans ce cas, le faible typage du langage provoque en fait une quantit√© importante de cas extr√™mes qui doivent √™tre trait√©s, ou vous obtenez du code qui va ūüí• qui n'est pas ce n'est bon pour personne. Je ne pense pas que si vous introduisez un op√©rateur comme celui-ci, vous puissiez r√©ellement r√©duire sa port√©e. Il serait plus facile pour les impl√©menteurs de couvrir 90¬†% des cas, mais je ne pense pas que ¬Į\_(„ÉĄ)_/¬Į soit un code valide pour les 10¬†% restants.

Les gars, plus de 3 ans plus tard, je dirais qu'il est temps de dire "va te faire foutre" au comité et de le faire à notre manière, quel que soit l'idiome de TypeScript. Cette fonctionnalité ne peut pas fonctionner correctement sans typage statique de toute façon.

Faites une implémentation TypeScript avec une syntaxe qui est explicitement incompatible avec la proposition TC39. Une fois qu'ES obtient un opérateur de navigation sécurisée, TypeScript aura deux options : une avec une sémantique de merde compatible avec ES et une qui est liée au système de type. Cela signifie que vous ne pouvez pas utiliser l'opérateur TS safe-nav avec n'importe quel "type", et c'est très bien.

@notsnotso Typescript n'est pas censé casser JS, c'est à cela que sert Coffeescript.

Peut-être qu'une bonne solution consiste à :

  • mise en oeuvre tr√®s simple ? op√©rateur pour les d√©veloppeurs impatients, en tant que fonctionnalit√© exp√©rimentale (comme le d√©corateur), avec avertissement - il cassera votre code √† l'avenir
  • attendez encore 3 ans lorsque le standart sera √©crit, impl√©mentez-le en tant que fonctionnalit√© non exp√©rimentale. Ecrire tutoriel, ce qui pourrait √™tre cass√©. M√™me, avec le typage statique, il est possible d'√©crire des avertissements lorsque les gens compileront du code avec une nouvelle impl√©mentation d'op√©rateur.
    "faites-le à notre manière, tout ce qui est idiomatique pour TypeScript" n'est pas un cas, car dans 3 ans, les gens seront confrontés à un problème, que ts elvis ne fonctionne pas de la même manière que dans js.

Je ne suis pas surpris que cela ne se soit pas passé, pour être honnête. Dans mon original
post, j'ai soulign√© l'ambigu√Įt√© concernant l'indexation, les appels de fonction, etc.
Honnêtement, plus je pense à ?. , plus j'ai l'impression que ce n'est pas le cas
appartiennent à JavaScript, puisqu'il a undefined .

Je préférerais de loin un utilitaire plus généraliste qui résoudrait ce problème
et plus. Une pensée que j'avais était quelque chose comme un try/catch en ligne
expression ( let x = try a.b.c else 0 ) en conjonction avec un opérateur qui
v√©rifi√© pour "nully" (par exemple, x ?? 1) plut√īt que "falsey" (par exemple, x || 1).
Donc, vous les combineriez comme ceci : try a.b.c ?? 0 else 0 . C'est verbeux, oui,
mais il dit essentiellement : Essayez d'évaluer abc et si le résultat est null ou
undefined , renvoie 0. Si a ou b vaut undefined et qu'une exception est levée,
attrapez-le et renvoyez un 0.

Une alternative serait de rendre la clause else facultative, par défaut à
undefined . Ensuite, vous pouvez √©crire l'expression sous la forme : let x= (try a.b.c) ?? 0 . C'est sacr√©ment compact, √©vite l'ambigu√Įt√© et offre un plus
solution polyvalente qui peut résoudre d'autres problèmes.

Je ne dis pas que nous devrions pousser pour cela à la place ; tout ce que je dis est là
sont des alternatives à ?. et nous devrions vraiment explorer nos options jusqu'à ce que nous
trouvez-en un qui correspond bien au langage JavaScript.

Le jeudi 5 octobre 2017 √† 7h51, Dmitry Radkovskiy [email protected]
a écrit:

@notsnotso Typescript n'est pas censé casser JS, c'est ce que
Coffeescript est fait pour.

‚ÄĒ
Vous recevez ceci parce que vous avez été mentionné.
Répondez directement à cet e-mail, consultez-le sur GitHub
https://github.com/Microsoft/TypeScript/issues/16#issuecomment-334441781 ,
ou couper le fil
https://github.com/notifications/unsubscribe-auth/ABTgPilbZfuKc2egdBrYfdTHHeDl3F6Sks5spMLLgaJpZM4CNapf
.

@zlumer belle blague. Cela dit, une fonctionnalité spécifique à TS ne casserait pas Javascript.

@jehugaleahsa J'aime votre proposition, et on la trouve dans d'autres langues. Je pense que cela fonctionnerait très bien pour TS.

Je dirai que je ne comprends pas vraiment la forte nécessité d'attendre qu'ECMAScript accepte l'opérateur. TypeScript a ajouté des classes, des modules, des lambdas, bien avant qu'ils ne se retrouvent dans ECMAScript. En fait, l'un des objectifs déclarés de TypeScript était/est de piloter des fonctionnalités JS expérimentales. TypeScript fournissant sa propre implémentation aiderait sans aucun doute à éclairer ces discussions au sein du comité.

Vous avez déjà été prêts à apporter des changements de rupture lorsque le comité a finalement pris une direction différente, je ne vois pas vraiment pourquoi cette fonctionnalité est si différente.

async/wait a également été introduit dans TypeScript à un stade précoce.

Cela dit, une fonctionnalité spécifique à TS ne casserait pas Javascript.

Il n'y aura pas quelque chose comme "fonctionnalité spécifique à TS", veuillez vérifier les objectifs de conception de TypeScript pour plus d'informations.

TypeScript arrive avant que ES n'emprunte un chemin lumineux, il pourrait y en avoir déjà,ils sont juste conservés pour la compatibilité.

TypeScript a ajouté des classes, des modules, des lambdas, bien avant qu'ils ne se retrouvent dans ECMAScript.

Et les modules en particulier sont une √©norme d√©b√Ęcle qui ne cause toujours pas de confusion. C'est un exemple que l'√©quipe TypeScript a utilis√© √† plusieurs reprises comme exemple de _mistake_ et de sauter le pistolet trop t√īt. Nous avons √©galement des champs priv√©s qui se profilent maintenant, ce qui, encore une fois, je suis reconnaissant pour private au cours des 5 derni√®res ann√©es, mais cela ne causera pas de confusion.

Encore une fois, les décorateurs étaient disponibles sous le drapeau, mais maintenant que les décorateurs arrivent à l'étape 3, cela nécessitera une réimplémentation et une rupture de code pour TypeScript. C'est pourquoi ces choses _ne peuvent pas_ être considérées comme probables.

async/wait a également été introduit dans TypeScript à un stade précoce.

Une fois que la proposition ECMAScript a atteint l'étape 3.

Personne ne se comporte mal, mais si cette conversation ne peut aller nulle part, mais en cercles (et s'il y avait un drapeau¬†? Oui, nous sommes conscients des drapeaux) ou hors sujet (et si TS cesse d'√™tre JS¬†? Non, cinq ans plus tard, nous ne changeons pas notre esprit l√†-dessus), nous n'avons pas besoin de l'avoir. Nous disons depuis environ 3 ans maintenant que nous mettrons cela en Ňďuvre exactement lorsque le comit√© ES verrouillera sa s√©mantique.

Encore une fois, le d√©p√īt de proposition est https://github.com/tc39/proposal-optional-chaining et vous pouvez y suivre sa progression. Nous travaillerons hors ligne pour essayer d'am√©liorer les chances de la proposition lors de la prochaine r√©union du TC39, car nous voulons vraiment que cela se concr√©tise √©galement.

Mise à jour : Nous avons atteint l'étape 2 cet après-midi au TC39 !!!

Le cha√ģnage facultatif est l'√©tape 3

Déverrouiller brièvement celui-ci uniquement à des fins de célébration

Hourra !

Ne spammez pas...

Vous pouvez envoyer un emoji exprimant vos sentiments

Ne spammez pas...

Vous pouvez envoyer un emoji exprimant vos sentiments

De plus, c'est amusant de voir le nombre d'emoji grimper comme ça. Je n'ai jamais vu un commentaire sur un problème gagner autant de popularité aussi vite !

J'ai enregistré une petite vidéo des mises à jour en temps réel https://youtu.be/JLBrgPjeGhc

Est-ce que quelqu'un peut me désabonner de cette chose ?

@DanielRosenwasser Au cas o√Ļ vous ne plaisanteriez pas, ou pour toute autre personne qui souhaite se d√©sinscrire et ne sait pas comment, vous recherchez ce bouton dans la barre lat√©rale de droite¬†:

image

Sans oublier qu'il y a un lien dans l'e-mail :

image

C'était une blague, je travaille sur la proposition.

@RyanCavanaugh après avoir déverrouillé ce problème :
martian

Vraiment h√Ęte de le voir enfin d√©barquer ! ūüéą ūüéČ

Je ne peux pas attendre la solution rapide VSCode correspondante ūüėÜ

image

Je vais à @ @RyanCavanaugh car il est probablement désabonné de ce fil et je veux être grossier ! (et @DanielRosenwasser pour faire bonne mesure)

@kitsonk Ne sois pas un √Ęne. Les gens sont libres de se d√©sabonner et de ne pas √™tre harcel√©s.

@kitsonk , Pourquoi RyanCavanaugh ou DanielRosenwasser seraient-ils désabonnés de ce fil ? Ryan a déverrouillé ce problème et Daniel a répondu trois commentaires au-dessus de vous.

Même s'ils étaient désabonnés, il n'est pas nécessaire de causer plus de fatigue de notification en les spammant.

Apparemment, GitHub est un endroit terrible pour l'humour sarcastique, bon sang...

Un grand merci à nos champions du TC39 pour avoir compris les détails désagréables de cette nouvelle fonctionnalité de langage !

thanks

Je pense que @kitsonk plaisantait, tout comme moi. Bien que nous soyons un peu idiots face à l'excitation, ceci est un doux rappel de garder les choses civiles conformément au CoC.

@DanielRosenwasser
Pourrais-je avoir √† essayer cela? Ou @rbuckton a encore une autre branche existante pour √ßa ūüôčūüŹĽ‚Äć‚ôāÔłŹ


Ok, j'ai compris https://github.com/microsoft/TypeScript/commits/optionalChainingStage1 ūü§¶ūüŹĽ‚Äć‚ôāÔłŹ

Oui, c'est assez obsolète, malheureusement.

Je viens de réaliser que ce sujet a été ouvert il y a 5 ans. :étonné:

@rbuckton

Oui, c'est assez obsolète, malheureusement.

Pourrais-je essayer ça ?

Désolé @jhpratt @MatthiasKunnen J'ai oublié que nous ne partageons pas tous le même contexte sur GitHub. Je rebondis ici depuis longtemps et j'ai passé du temps avec Ryan et Daniel IRL et j'ai brièvement participé à l'événement récent qui a donné lieu à ma blague incomprise. Excuses.

Tout ce num√©ro montre cependant une arch√©ologie int√©ressante des principes de conception de TypeScript. Ryan l'a soulev√© √† un moment o√Ļ TypeScript _pourrait_ avoir en fait envisag√© une syntaxe ant√©rieure √† une consid√©ration s√©rieuse dans ECMAScript. C'est √† cette √©poque que TypeScript apprenait en interne quelques le√ßons de pr√©diction de la syntaxe ES2015 qui avaient de s√©rieux impacts sur le langage. L'√©quipe a d√©cid√© de ne pas envisager l'inclusion jusqu'√† ce qu'il y ait une proposition TC39 Stage 3.

Bien que @RyanCavanaugh puisse y r√©pondre, et je sais qu'il a √©t√© proche de ce qui s'est pass√© avec la proposition, je soup√ßonne qu'il aurait √©t√© peu probable que ce que l'√©quipe aurait mis en Ňďuvre en 2014 aurait √©t√© compatible √† 100% avec la proposition actuelle de l'√©tape 3 . Donc, bien que ce soit certainement une c√©l√©bration, soyez √©galement reconnaissant que nous n'ayons pas 5 ans de code TypeScript avec un op√©rateur de navigation s√Ľr qui ne serait pas enti√®rement coh√©rent avec le comportement de la proposition.

ūüôŹ

westwing

Est-ce le moment de retirer le label Waiting for TC39 ? ūü§Ē

Est-ce le moment de retirer le label Waiting for TC39 ? ūü§Ē

Et ajoutez ship-it

wowowow

Finalement. Litt√©ralement, je posais des questions sur le cha√ģnage facultatif, je me demandais quand ce serait l'√©tape 3, et bam¬†! Merci √† tous ceux qui ont travaill√© pour le faire passer!

Comment mettre ce fil en sourdine ? :)

@opnksyn Si vous ne vous souciez pas de l'excitation du spam, il existe une fonctionnalit√© pour √™tre averti lorsque ce probl√®me est ferm√©. Cela emp√™chera tous les commentaires d'appara√ģtre dans les notifications comme celle que vous venez de faire ūüėĄ

image

image

Une solution d'émission déjà définie ?
Quelque chose comme ça pourrait être intéressant :

function __chain<T extends object, U>(value: T|null|undefined, callback: (value: T) => U): U|undefined {
    if (value !== null && value !== undefined) {
        return callback(value);
    }

    return undefined;
}

type Foo = { x?: { y?: { z?: () => number } } }

const foo: Foo|null = { }

// foo?.x?.y?.z?()
const value = __chain(foo, _a => __chain(_a.x, _b => __chain(_b.y, _c => __chain(_c.z, _d => _d()))));

Je préfère ce que fait Babel car cela évite de créer des portées de fonction inutiles :

var _foo, _foo$x, _foo$x$y, _foo$x$y$z;

// foo?.x?.y?.z?.()
(_foo = foo) === null || _foo === void 0 ? void 0
    : (_foo$x = _foo.x) === null || _foo$x === void 0 ? void 0
    : (_foo$x$y = _foo$x.y) === null || _foo$x$y === void 0 ? void 0
    : (_foo$x$y$z = _foo$x$y.z) === null || _foo$x$y$z === void 0 ? void 0
    : _foo$x$y$z.call(_foo$x$y);

Je préfère ce que fait Babel car cela évite de créer des portées de fonction inutiles :

var _foo, _foo$x, _foo$x$y, _foo$x$y$z;

// foo?.x?.y?.z?.()
(_foo = foo) === null || _foo === void 0 ? void 0
  : (_foo$x = _foo.x) === null || _foo$x === void 0 ? void 0
  : (_foo$x$y = _foo$x.y) === null || _foo$x$y === void 0 ? void 0
  : (_foo$x$y$z = _foo$x$y.z) === null || _foo$x$y$z === void 0 ? void 0
  : _foo$x$y$z.call(_foo$x$y);

Je suis d'accord, @ExE-Boss. Je pense qu'éviter de créer des portées de fonctions inutiles est idéal (même si cela rend le code compilé un peu moche)

Les performances et le respect de la spécification ES devraient définitivement l'emporter sur la lisibilité lorsqu'il s'agit de code compilé.

Y a-t-il une raison pour laquelle le code compilé par Babel se compare à la fois à null et void 0 avec un triple égal au lieu d'un simple == null ?

Y a-t-il une raison pour laquelle le code compilé par Babel se compare à la fois à null et void 0 avec un triple égal au lieu d'un simple == null ?

@proteria Je viens de jeter un coup d'Ňďil au code de cha√ģnage optionnel pour __Babel__ ; il semble que si vous passez l'option loose et que vous la r√©glez sur une valeur de v√©rit√©, cela ne produit pas les contr√īles d'√©galit√© stricts

C'est à cause de document.all (ou pour être pédant, le slot interne [[IsHTMLDDA]] ), une bizarrerie qui reçoit un traitement spécial dans le langage pour une compatibilité descendante.

document.all == null // true
document.all === null || document.all === undefined // false

Dans la proposition de cha√ģnage optionnel

document.all?.foo === document.all.foo

mais document.all == null ? void 0 : document.all.foo renverrait incorrectement void 0 . En mode l√Ęche, ce d√©tail de la sp√©cification est ignor√© pour la simplicit√©/les performances/la taille du code g√©n√©r√©, car la plupart des gens n'ont de toute fa√ßon pas √† g√©rer document.all .

Le cas document.all pourrait s√Ľrement √™tre sp√©cial¬†? Cela ne devrait pas n√©cessiter beaucoup de code suppl√©mentaire, juste quelques lignes pour v√©rifier l'objet et la propri√©t√©.

Sauf que document.all peut être affecté à une variable, et le suivi de son utilisation nécessite un système de type, c'est pourquoi Babel affiche par défaut :

(_prop = prop) === null || _prop === void 0 ? void 0 : _prop./* do stuff */;

Je suis au courant de ça. Babel n'a pas de système de typage, contrairement à TypeScript. Ce n'est peut-être pas aussi simple que je l'ai dit, mais j'imagine qu'il existe déjà du code pour certaines situations qui est capable de suivre l'utilisation.

En fait, vous n'avez pas besoin d'un système de type pour suivre les variables document.all , car le comportement spécial est en fait sur HTMLAllCollection , et non document.all .

Donc, vous devriez juste pouvoir faire un instanceof HTMLAllCollection , et vous serez en or.

Ouais mais... pourquoi as-tu fait instanceof alors que tu peux juste faire === null || === void 0¬†? C'est s√Ľrement plus simple.

Bien s√Ľr - je faisais juste remarquer que vous n'avez pas besoin d'un syst√®me de type pour suivre document.all :)

Personnellement, je suis tenté de dire qu'il suffit de le casser et de voir qui se plaint, mais c'est dans les spécifications, il est donc plus facile de s'en tenir à cela.

@noppa Il peut être effectué au moment de la compilation. Si foo instanceof HTMLAllCollection est true , émettez foo === null || foo === void 0 , sinon nous pouvons _en toute sécurité_ émettre foo == null .

@G-Rath Qu'on le veuille ou non, obsolète ne signifie pas que cela ne devrait pas fonctionner. TypeScript doit rester compatible avec JavaScript.

@jhpratt Mais cela va actuellement à l'encontre des non-objectifs de conception de TypeScript .

De plus, vous devrez toujours faire foo === null || foo === void 0 pour tout ce à quoi HTMLAllCollection pourrait être attribué, par exemple. any ou object , donc je ne pense pas que ça en vaille vraiment la peine.

Je suppose que vous faites référence au non-objectif (5)

Ajouter ou s'appuyer sur les informations de type d'exécution dans les programmes, ou émettre un code différent en fonction des résultats du système de type. Au lieu de cela, encouragez les modèles de programmation qui ne nécessitent pas de métadonnées d'exécution.

Bien que je convienne que cela émettrait certainement un code différent en fonction du type, c'est uniquement pour réduire la taille du code. Bien que, comme vous l'avez souligné, ce n'est pas aussi simple que de vérifier HTMLAllCollection .

Pour √™tre juste, TS _a_ rejet√© un minificateur potentiel qui utilise des informations de type, et ceci est (en quelque sorte) li√© ‚ÄĒ la principale raison d'√©mettre == null est de r√©duire la taille du code en fonction des informations de type.

Si cela _n'est pas_ implémenté, ce serait formidable si l'équipe lang ajoutait une option à tsconfig similaire à l'option "loose" de Babel.

Apr√®s une v√©rification rapide, terser convertit automatiquement foo === null || foo === undefined en foo == null , ce qui n'est pas s√Ľr en raison de ce cas limite.

Si cela n'est pas implémenté, ce serait formidable si l'équipe lang ajoutait une option à tsconfig similaire à l'option "loose" de Babel.

De même, beaucoup d'entre nous utilisent TypeScript pour les outils de construction et pour les applications mobiles, dont aucun n'a à se soucier des contraintes du navigateur !

En fait, nous utilisons à la fois TS et Babel ensemble, donc peut-être que l'une de ces options devrait être de passer l'opérateur à Babel/runtime sous-jacent !

@fbartho

En fait, nous utilisons à la fois TS et Babel ensemble, donc peut-être que l'une de ces options devrait être de passer l'opérateur à Babel/runtime sous-jacent !

Je ne comprends pas ce commentaire. Vous n'avez pas besoin d'options supplémentaires pour passer l'opérateur à Babel ; si vous avez configuré TypeScript pour Babel, vous avez déjà noEmit: true qui transmet déjà _tout_ à Babel.

L'implémentation TypeScript de @ Zarel Babel manque plusieurs fonctionnalités sur lesquelles notre base de code s'appuyait déjà, y compris les espaces de noms et les énumérations constantes. Nous utilisons TSC avec l'émission activée et appliquons Babel comme deuxième transformation. (Nous travaillons sur la suppression des espaces de noms, mais il n'est pas clair si nous pourrons un jour nous débarrasser de toutes les fonctionnalités incompatibles)

Les personnes venant sur ce fil de discussion devraient commencer √† l' annonce de l'√©tape 3 pr√©c√©dente et lire les commentaires √† partir de l√† (bl√Ęmez GitHub pour avoir cach√© des tonnes de contenu utilisateur sans moyen simple de tout charger)

Grande fonctionnalit√© - "cha√ģnage en option" / "navigation s√Ľre". Surtout en mode strict TypeScript. G√©nial d'entendre que cela sera bient√īt mis en Ňďuvre. ‚̧ԳŹ

Cela m'a amené ici et j'espère qu'il sera soutenu. Juste un cas d'utilisation :

Attendu dans TypeScript 3.7.

document.querySelector('html')?.setAttribute('lang', 'en');

VS

Actuellement dans TypeScript 3.5.

const htmlElement = document.querySelector('html');
if (htmlElement) {
  htmlElement.setAttribute('lang', 'en');
}

Cela fonctionnera-t-il sans aucune erreur¬†? Ou est-ce toujours un TypeError: Cannot read property 'setAttribute' of null.¬†? L' ? . devrait √™tre annuler d'autres cha√ģnes apr√®s null / undefined.

class Test {
  it() {
    console.log('One');
    document.querySelector('html')?.setAttribute('lang', 'en');
    console.log('Two');
  }
}
new Test().it();

J'attends la suite :
Si l'élément html n'existe pas (null). La console doit enregistrer One et Two , et la méthode setAttribute n'est pas tentée d'être invoquée. (Aucune erreur).
Est-ce que j'ai bien compris ?

@domske FYI, ce n'est pas strictement une fonctionnalité TS ; c'est une fonctionnalité JS.

Selon la proposition du TC39, la syntaxe sera :

document.querySelector('html')?.setAttribute?.('lang', 'en');

La discussion a recommencé à tourner en rond, nous sommes donc revenus à l'état verrouillé.

Je supplie vraiment toute personne tentée de laisser un commentaire dans un fil GitHub de plus de 100 commentaires de s'engager vraiment à lire tous les commentaires précédents en premier. Votre question et la réponse y seront probablement trouvées !

Cette page vous a été utile?
0 / 5 - 0 notes

Questions connexes

weswigham picture weswigham  ¬∑  3Commentaires

dlaberge picture dlaberge  ¬∑  3Commentaires

wmaurer picture wmaurer  ¬∑  3Commentaires

uber5001 picture uber5001  ¬∑  3Commentaires

DanielRosenwasser picture DanielRosenwasser  ¬∑  3Commentaires