¿Por qué el operador && producir el tipo del segundo operando

votos
24

La especificación de transcripción en §4.15.6 acerca del &&operador:

El operador && permite que los operandos a ser de cualquier tipo y produce un resultado del mismo tipo que el segundo operando .

En Javascript, el &&operador devuelve el primer operando si es Falsy, de lo contrario, devuelve el segundo operando ( ver ECMA-262 §11.11 ).

Eso significa que si el operando de la izquierda es Falsy, &&devolverá un valor que coincida con el tipo del operando de la izquierda. Por ejemplo,

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

Letra de imprenta, de acuerdo con la norma citada más arriba, sería incorrectamente predecir los tipos de las expresiones anteriores sean Object, Number, Stringy Boolean, respectivamente.

¿Me estoy perdiendo de algo? ¿Hay una buena razón para hacer el tipo de una &&expresión coincide con el tipo del segundo operando? No debería el tipo de resultado se comporta como el ||operador, y devolver el mejor tipo común de los dos operandos, y Anysi no hay tipo más común?

Publicado el 02/10/2012 a las 16:50
fuente por usuario
En otros idiomas...                            


1 respuestas

votos
20

Para resumir, no hay ninguna solución a este problema que agrada a todos.

Considere este lenguaje común:

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
}

Sería bastante cojo a renunciar y decidir que 'dirección' es 'cualquiera' porque no hay mejor tipo común entre el Cliente y Dirección.

En la mayoría de los casos en que se utiliza el operador &&, ya sea los tipos ya coinciden, o && está siendo utilizado de manera coalescente valor como anteriormente. En cualquier caso, volviendo el tipo del operando derecho le da al usuario el tipo esperado.

Mientras que la seguridad de tipos es técnicamente rompiendo en este punto, no es hacerlo de una manera que es probable que resulte en un error. Ya sea que vas a probar el valor resultante de truthiness (en cuyo caso el tipo es más o menos irrelevante), o vas a usar el operando presuntiva adecuado para alguna operación (el ejemplo anterior haciendo ambas cosas).

Si nos fijamos en los ejemplos que enumeró y pretender que el operando de la izquierda es indeterminada Truthy o Falsy y luego tratar de escribir código cuerdo que operaría en el valor de retorno, se hace mucho más claro - no es sólo la cantidad que puede hacer con la 'falsa && {}' que aún no está entrando en una 'cualquier' posición de argumento o prueba truthiness.


Apéndice

Ya que algunas personas no estaban convencidos de lo anterior, he aquí una explicación diferente.

Vamos a suponer por un momento que el sistema de tipos mecanografiado agregó tres nuevos tipos: Truthy<T>, Falsy<T>y Maybe<T>, en representación de los valores posibles Truthy / Falsy de tipo T. Las reglas para estos tipos son los siguientes:

  1. Truthy<T> se comporta exactamente igual T
  2. No se puede acceder a las propiedades de Falsy<T>
  3. Una expresión de tipo Maybe<T>, cuando se utiliza como la condición en un ifbloque, se convierte en una Truthy<T>en el cuerpo de ese mismo ifbloque y una Falsy<T>en el elsebloque

Esto permitirá hacer cosas como esta:

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!
}

Bastante bueno hasta ahora. Ahora podemos averiguar cuáles son las reglas de tipos son para el operador &&.

  • Truthy<T> && x debe ser un error - Si el lado izquierdo es conocido por ser Truthy, debe acaba de escribir x
  • Falsy<T> && xdebe ser un error - Si el lado izquierdo es conocido por ser Falsy, xes código inalcanzable
  • Maybe<T> && x debe producir ... ¿qué?

Sabemos que el resultado de la Maybe<T> && xserá o bien un valor Falsy de tipo T, o x. No se puede producir Truthy<T>(a menos que T== del tipo de xen cuyo caso toda esta discusión es discutible). Vamos a llamar a este nuevo tipo Falsy<T> XOR Maybe<U>.

¿Qué deben las reglas de Falsy<T> XOR Maybe<U>ser?

  • Claramente, no se puede utilizar las propiedades de Tsobre ella. Si el valor es de tipo T, es Falsy, y no es seguro para su uso.
  • Usted debe ser capaz de utilizarlo como Maybe<U>, desde Falsy<T>y Falsy<U>tienen el mismo comportamiento
  • No debería ser capaz de utilizar las propiedades de U, ya que el valor aún podría ser Falsy.
  • Si lo usa en una ifprueba, entonces debe convertirse en una Truthy<U>en el bloque de esa ifdeclaración

En otras palabras, Falsy<T> XOR Maybe<U> es Maybe<U> . De ello se sigue todas las mismas reglas. No es necesario complicar el sistema de tipos a todos aquí por la adición de este raro XORtipo, debido a un tipo que se adapte a todas las especificaciones que necesita ya existe.

Esto es un poco como darle a alguien una caja y decir "esto es ya sea una caja vacía de la basura, o una caja llena de materiales reciclables". Puede vaciar de forma segura el contenido de la caja en la papelera de reciclaje.

Respondida el 02/10/2012 a las 17:55
fuente por usuario

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more