Domanda

La specifica TypeScript afferma nel §4.15.6 && operatore:

L'operatore & & consente agli operandi di essere di qualsiasi tipo e produce un risultato dello stesso tipo del secondo operando.

In Javascript, il && l'operatore restituisce il primo operando se è falso, altrimenti restituisce il secondo operando (vedi ECMA-262 §11.11).

Ciò significa che se l'operando sinistro è falso, && restituirà un valore che corrisponde al tipo dell'operando sinistro.Biru,

typeof ( false && {}      ) === "boolean" // true
typeof ( ''    && 1       ) === "string"  // true
typeof ( null  && "hello" ) === "object"  // true
typeof ( NaN   && true    ) === "number"  // true

Dattiloscritto, secondo la regola sopra citata, sarebbe errato predire i tipi delle espressioni di cui sopra per essere Object, Number, String e Boolean, rispettivamente.

Mi sto perdendo qualcosa?C'è una buona ragione per fare il tipo di un && espressione corrisponde al tipo del secondo operando?Il tipo di risultato non dovrebbe comportarsi come il || operatore, e restituisce il miglior tipo comune dei due operandi, e Any se non esiste il miglior tipo comune?

È stato utile?

Soluzione

Per farla breve, non c'è soluzione qui che piaccia a tutti.

Considera questo idioma comune:

var customer = GetCustomer(...); // of type 'Customer'
var address = customer && customer.address;
if(address) {
    printAddressLabel(address); // Signature: (Address) => void
} else {
    // Couldn't find the customer or the customer has no address on file
}

Sarebbe piuttosto zoppo rinunciare e decidere che 'indirizzo' è 'qualsiasi' perché non esiste il miglior tipo comune tra Cliente e Indirizzo.

Nella maggior parte dei casi in cui viene utilizzato l'operatore&&, i tipi gi match, o & & viene utilizzato in un modo di coalescenza del valore come sopra.In entrambi i casi, la restituzione del tipo dell'operando destro fornisce all'utente il tipo previsto.

Mentre la sicurezza del tipo è tecnicamente in rottura a questo punto, non lo fa in un modo che rischia di provocare un errore.O stai per testare il valore risultante per la verità (nel qual caso il tipo è più o meno irrilevante), o userai l'operando destro presuntivo per alcune operazioni (l'esempio sopra facendo entrambi).

Se guardiamo gli esempi che hai elencato e fingiamo che l'operando sinistro sia indeterminatamente veritiero o falso e quindi proviamo a scrivere codice sano che operi sul valore restituito, diventa molto più chiaro-non c'è molto che puoi fare con ' false & & {} 'che non sta già entrando in una posizione di argomento' qualsiasi ' o test di veridicità.


Addendum

Dal momento che alcune persone non erano convinte da quanto sopra, ecco una spiegazione diversa.

Facciamo finta per un momento che il sistema di tipo TypeScript abbia aggiunto tre nuovi tipi: Truthy<T>, Falsy<T>, e Maybe<T>, rappresentando possibili valori veritieri / falsi di tipo T.Le regole per questi tipi sono le seguenti:

  1. Truthy<T> si comporta esattamente come T
  2. Non è possibile accedere a nessuna proprietà di Falsy<T>
  3. Un'espressione di tipo Maybe<T>, una volta usato come la circostanza in un if blocco, diventa un Truthy<T> nel corpo di quella stessa if blocco e a Falsy<T> nel else blocco

Questo ti permetterebbe di fare cose del genere:

function fn(x: Maybe<Customer>) {
   if(x) {
      console.log(x.address); // OK
   } else {
      console.log(x.phone); // Error: x is definitely falsy
   }
   console.log(x.name); // Warning: x might be falsy!
}

Abbastanza buono finora.Ora possiamo capire quali sono le regole del tipo per l'operatore&&.

  • Truthy<T> && x dovrebbe essere un errore-se il lato sinistro è noto per essere veritiero, dovresti aver appena scritto x
  • Falsy<T> && x dovrebbe essere un errore-se il lato sinistro è noto per essere falso, x è un codice irraggiungibile
  • Maybe<T> && x dovrebbe produrre...Che?

Conosciamo il risultato di Maybe<T> && x sarà un valore falso di tipo T, o x.Non può produrre Truthy<T> (tranne T = = il tipo di x nel qual caso l'intera discussione è discutibile).Chiamiamo questo nuovo tipo Falsy<T> XOR Maybe<U>.

Quali dovrebbero essere le regole di Falsy<T> XOR Maybe<U> essere?

  • Chiaramente, non puoi usare le proprietà di T su di esso.Se il valore è di tipo T, è falso, e non sicuro per uso.
  • Dovresti essere in grado di usarlo come un Maybe<U>, poiché Falsy<T> e Falsy<U> hanno gli stessi comportamenti
  • Non dovresti essere in grado di usare le proprietà di U, perché il valore ancora potrebbe essere falso.
  • Se lo si utilizza in un if test, allora dovrebbe diventare un Truthy<U> nel blocco di quella if dichiarazione

In altre parole, Falsy<T> XOR Maybe<U> essere Maybe<U>.Segue tutte le stesse regole.Non è necessario complicare il sistema di tipi qui aggiungendo questo strano XOR tipo, perché esiste già un tipo che soddisfa tutte le specifiche necessarie.

Questo è un po ' come dare a qualcuno una scatola e dire "Questa è una scatola vuota di spazzatura o una scatola piena di materiali riciclabili".È possibile svuotare in modo sicuro il contenuto della scatola nel cestino.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top