TypeScript

TypeScript

Tutorial TypeScript: Operadores y expresiones

TypeScript operadores: manejo y ejemplos. Domina el manejo de operadores en TypeScript mediante ejemplos prácticos y detallados.

Aprende TypeScript y certifícate

Operadores aritméticos y de comparación

Los operadores son símbolos especiales que realizan operaciones sobre variables y valores. En TypeScript, al ser un superconjunto de JavaScript, encontramos los mismos operadores pero con la ventaja del sistema de tipos que nos ayuda a detectar errores comunes durante el desarrollo.

Operadores aritméticos

Los operadores aritméticos realizan operaciones matemáticas entre valores numéricos. TypeScript verifica que estos operadores se apliquen a tipos compatibles.

  • Suma (+): Suma dos números o concatena strings.
const sum: number = 5 + 3;         // 8
const greeting: string = "Hello " + "World"; // "Hello World"

// TypeScript detecta errores de tipo
const error = "42" + 10;           // "4210" (concatenación, no suma)
const typedSum = parseInt("42") + 10; // 52 (suma numérica correcta)
  • Resta (-): Resta el segundo operando del primero.
const difference: number = 10 - 4; // 6
const negation: number = -5;       // Operador unario de negación
  • Multiplicación (*): Multiplica dos valores numéricos.
const product: number = 6 * 7;     // 42
  • División (/): Divide el primer operando por el segundo.
const quotient: number = 20 / 4;   // 5
const decimal: number = 10 / 3;    // 3.3333...
  • Módulo (%): Devuelve el resto de la división.
const remainder: number = 10 % 3;  // 1
  • Exponenciación (**): Eleva el primer operando a la potencia del segundo.
const power: number = 2 ** 3;      // 8 (2³)
  • Incremento (++) y Decremento (--): Aumentan o disminuyen un valor en 1.
let counter: number = 5;
counter++;                         // Ahora counter es 6
counter--;                         // Ahora counter es 5 de nuevo

// Diferencia entre prefijo y postfijo
let a: number = 5;
let b: number = a++;               // b = 5, a = 6 (postfijo)
let c: number = 5;
let d: number = ++c;               // d = 6, c = 6 (prefijo)

Operadores de comparación

Los operadores de comparación son herramientas fundamentales en programación que nos permiten tomar decisiones. Son como hacer preguntas sobre la relación entre dos valores, y la respuesta siempre es binaria: true (verdadero) o false (falso).

  • Igual/Comparación débil (==):

Este operador compara si dos valores son iguales después de realizar conversiones de tipo si es necesario.

// Igual (==) - compara valor, con conversión de tipos
console.log(5 == 5);               // true
console.log("5" == 5);             // true, convierte implícitamente el string "5" al número 5. Una vez que ambos son números (5 == 5), la comparación es true.

En TypeScript, se recomienda usar siempre el operador de igualdad estricta (===) para evitar comportamientos inesperados por conversión de tipos.

  • Estrictamente igual (===):

Este operador es mucho más "estricto". Compara si dos valores son iguales Y si son del mismo tipo, sin realizar conversiones de tipo implícitas.

// Estrictamente igual (===) - compara valor y tipo
console.log(5 === 5);              // true
console.log("5" === 5);            // false (tipos diferentes)
  • Diferente (!=) y Estrictamente diferente (!==):
// Diferente (!=)
console.log(5 != 8);               // true
console.log("5" != 5);             // false (conversión implícita)

// Estrictamente diferente (!==)
console.log(5 !== 8);              // true
console.log("5" !== 5);            // true (tipos diferentes)
  • Mayor que (>), Menor que (<), Mayor o igual (>=), Menor o igual (<=):
const x: number = 10;
const y: number = 5;

console.log(x > y);                // true
console.log(x < y);                // false
console.log(x >= 10);              // true
console.log(y <= 5);               // true

Comparaciones con tipos específicos

TypeScript nos ayuda a detectar comparaciones inválidas entre tipos incompatibles, al conocer los tipos de tus variables antes de que el código se ejecute (lo que llamamos análisis estático), puede detectar situaciones donde una comparación directa entre tipos incompatibles es muy probable que sea un error lógico o dependa de un comportamiento poco claro.

// El compilador de TypeScript mostrará advertencias
function compareValues(a: string, b: number): boolean {
    // Esta comparación podría no tener el resultado esperado
    return a > b; // TypeScript advierte sobre comparación de tipos diferentes
}

¿Qué ve TypeScript aquí?

  1. Ve que la variable a es declarada como string.
  2. Ve que la variable b es declarada como number.
  3. Ve que estás intentando usar el operador > para comparar a y b.

TypeScript sabe que comparar un string con un number usando > (o <) es, en la mayoría de los casos, una operación ambigua o que dependerá de las reglas internas de JavaScript para convertir uno u otro tipo antes de la comparación. Debido a esta ambigüedad y potencial fuente de errores, el compilador de TypeScript te emitirá una advertencia o un error.

Cuando realmente necesitas comparar valores de diferentes tipos (por ejemplo, un número que llegó como string desde un formulario web), la mejor práctica y lo que TypeScript fomenta es realizar una conversión de tipo explícita.

// Forma correcta: convertir explícitamente
function compareCorrectly(a: string, b: number): boolean {
    return Number(a) > b; // Conversión explícita
}

¿Qué pasa ahora?

  1. Tomas el valor de a (que es un string).
  2. Usas Number(a). Esto es una conversión explícita. Le estás diciendo a TypeScript: "Toma el valor del string a e inténtalo convertir en su representación numérica".
  3. El resultado de Number(a) será un number (si la conversión fue exitosa) o NaN (Not a Number, si el string no representaba un número válido, como "hola").
  4. Ahora la comparación es entre el resultado de Number(a) (que es un number) y b (que también es un number). Estás comparando dos number.

Operadores de comparación con objetos

Al comparar objetos, recuerda que se comparan por referencia, no por contenido:

const obj1 = { value: 10 };
const obj2 = { value: 10 };
const obj3 = obj1;

console.log(obj1 === obj2);        // false (diferentes referencias)
console.log(obj1 === obj3);        // true (misma referencia)

// Para comparar contenido, compara propiedades específicas
console.log(obj1.value === obj2.value); // true (mismo valor)

Uso práctico en condicionales

Los operadores de comparación son esenciales en las estructuras condicionales:

function checkAge(age: number): string {
    if (age >= 18) {
        return "Adult";
    } else if (age >= 13) {
        return "Teenager";
    } else {
        return "Child";
    }
}

// Uso con operador ternario
function getDiscount(isPremium: boolean, price: number): number {
    return isPremium ? price * 0.8 : price * 0.95;
}

Encadenamiento de comparaciones

A diferencia de algunos lenguajes, JavaScript y TypeScript no permiten encadenar comparaciones matemáticamente:

// Esto NO funciona como se esperaría
const value = 5;
const result = 1 < value < 10;     // Siempre true, independientemente de value

// Forma correcta
const correctResult = 1 < value && value < 10; // true si value está entre 1 y 10

Los operadores aritméticos y de comparación son la base para construir expresiones más complejas que controlarán el flujo de nuestras aplicaciones TypeScript. Dominarlos es fundamental para escribir código eficiente y libre de errores.

Operadores lógicos (AND, OR, NOT)

Los operadores lógicos en TypeScript permiten combinar expresiones booleanas para crear condiciones más complejas. Estos operadores son fundamentales para implementar la lógica de decisión en nuestras aplicaciones y trabajan con valores que se evalúan como verdadero (truthy) o falso (falsy).

Operador AND (&&)

El operador && (AND lógico) devuelve true solo cuando ambos operandos son verdaderos. Si el primer operando es falso, el segundo ni siquiera se evalúa (evaluación de cortocircuito).

const isAdult: boolean = true;
const hasPermission: boolean = true;

// Ambas condiciones deben ser true para obtener true
const canAccess: boolean = isAdult && hasPermission; // true

// Ejemplo con evaluación de cortocircuito
function checkAccess(age: number, role: string): boolean {
    return age >= 18 && role === "admin";
}

console.log(checkAccess(20, "admin")); // true
console.log(checkAccess(16, "admin")); // false (cortocircuito en la primera condición)

El operador && también se puede utilizar para ejecutar código condicionalmente:

// La función solo se ejecuta si user existe
const user = { name: "Alice", role: "admin" };
user && console.log(`Usuario: ${user.name}`); // Imprime "Usuario: Alice"

// Asignación condicional
const defaultConfig = { timeout: 1000, retries: 3 };
const userConfig = null;
const config = userConfig && userConfig.timeout ? userConfig : defaultConfig;

Operador OR (||)

El operador || (OR lógico) devuelve true si al menos uno de los operandos es verdadero. Si el primer operando es verdadero, el segundo no se evalúa (cortocircuito).

const hasLocalPermission: boolean = false;
const hasGlobalPermission: boolean = true;

// Al menos una condición debe ser true
const hasAccess: boolean = hasLocalPermission || hasGlobalPermission; // true

// Ejemplo práctico: valores predeterminados
function createUser(name: string, role?: string): { name: string, role: string } {
    return {
        name,
        role: role || "user" // Si role es undefined, usa "user"
    };
}

console.log(createUser("Bob")); // { name: "Bob", role: "user" }
console.log(createUser("Alice", "admin")); // { name: "Alice", role: "admin" }

Operador NOT (!)

El operador ! (NOT lógico) invierte el valor de verdad de su operando. Convierte true en false y viceversa.

const isLoggedIn: boolean = false;
const isGuest: boolean = !isLoggedIn; // true

// Verificación de valores nulos o indefinidos
const data: string | null = null;
if (!data) {
    console.log("No hay datos disponibles");
}

// Doble negación para convertir a booleano
const hasValue = !!"Hello"; // true
const isEmpty = !!""; // false

Valores truthy y falsy

En TypeScript, como en JavaScript, los valores se convierten implícitamente a booleanos en contextos lógicos. Es importante conocer qué valores se consideran falsy:

// Valores falsy en TypeScript
console.log(Boolean(false));     // false
console.log(Boolean(0));         // false
console.log(Boolean(""));        // false
console.log(Boolean(null));      // false
console.log(Boolean(undefined)); // false
console.log(Boolean(NaN));       // false

// Todos los demás valores son truthy
console.log(Boolean(true));      // true
console.log(Boolean(1));         // true (cualquier número excepto 0)
console.log(Boolean("hello"));   // true (cualquier string no vacío)
console.log(Boolean({}));        // true (cualquier objeto)
console.log(Boolean([]));        // true (cualquier array)

Operador de coalescencia nula (??)

El operador ?? devuelve el operando derecho solo cuando el izquierdo es null o undefined, a diferencia de || que evalúa cualquier valor falsy.

// Diferencia entre || y ??
const count = 0;
const defaultCount = 10;

// || considera 0 como falsy
const result1 = count || defaultCount; // 10

// ?? solo considera null o undefined
const result2 = count ?? defaultCount; // 0

// Ejemplo práctico
function fetchUserData(userId: string | null): { id: string, name: string } {
    const id = userId ?? "guest-user";
    return {
        id,
        name: id === "guest-user" ? "Invitado" : "Usuario registrado"
    };
}

Combinando operadores lógicos

Puedes combinar operadores lógicos para crear condiciones complejas:

type User = {
    age: number;
    role: string;
    isActive: boolean;
};

function canEditDocument(user: User | null, isOwner: boolean): boolean {
    // Verificar si el usuario existe, es activo, y tiene permisos
    return (
        !!user && 
        user.isActive && 
        (isOwner || user.role === "admin" || user.role === "editor")
    );
}

const admin: User = { age: 30, role: "admin", isActive: true };
console.log(canEditDocument(admin, false)); // true

const inactiveUser: User = { age: 25, role: "user", isActive: false };
console.log(canEditDocument(inactiveUser, true)); // false

Precedencia de operadores lógicos

La precedencia de los operadores lógicos es: ! (más alta), &&, || (más baja). Usa paréntesis para controlar el orden de evaluación:

// Sin paréntesis (por precedencia, && se evalúa antes que ||)
const result1 = true || false && false; // true

// Con paréntesis para cambiar el orden
const result2 = (true || false) && false; // false

// Ejemplo práctico
function checkEligibility(age: number, hasParentalConsent: boolean): boolean {
    // Los paréntesis aclaran la intención
    return age >= 18 || (age >= 13 && hasParentalConsent);
}

Los operadores lógicos son herramientas esenciales para controlar el flujo de ejecución y tomar decisiones en nuestras aplicaciones TypeScript. Dominar su comportamiento, especialmente las evaluaciones de cortocircuito, te permitirá escribir código más conciso y eficiente.

Operadores de asignación compuesta

Los operadores de asignación compuesta combinan una operación aritmética o lógica con una asignación en una sola expresión. Estos operadores permiten escribir código más conciso y legible al realizar operaciones sobre una variable y almacenar el resultado en la misma variable.

Operadores aritméticos compuestos

Estos operadores realizan una operación matemática y luego asignan el resultado:

  • Suma y asignación (+=):
let score: number = 10;
score += 5; // Equivalente a: score = score + 5
console.log(score); // 15

// También funciona con strings
let message: string = "Hello";
message += " World"; // Concatenación y asignación
console.log(message); // "Hello World"
  • Resta y asignación (-=):
let countdown: number = 10;
countdown -= 2; // Equivalente a: countdown = countdown - 2
console.log(countdown); // 8

// Uso práctico en un bucle
function countBackwards(start: number): number[] {
    const result: number[] = [];
    let current = start;
    
    while (current > 0) {
        result.push(current);
        current -= 1;
    }
    
    return result;
}

console.log(countBackwards(5)); // [5, 4, 3, 2, 1]
  • Multiplicación y asignación (*=):
let factor: number = 2;
factor *= 4; // Equivalente a: factor = factor * 4
console.log(factor); // 8

// Ejemplo: cálculo de interés compuesto
function calculateCompoundInterest(principal: number, rate: number, years: number): number {
    let amount = principal;
    for (let i = 0; i < years; i++) {
        amount *= (1 + rate); // Multiplica por el factor de interés
    }
    return amount;
}

console.log(calculateCompoundInterest(1000, 0.05, 3)); // 1157.63...
  • División y asignación (/=):
let value: number = 100;
value /= 2; // Equivalente a: value = value / 2
console.log(value); // 50

// Ejemplo: reducción progresiva
function halvingSequence(start: number, steps: number): number[] {
    const sequence: number[] = [];
    let current = start;
    
    for (let i = 0; i < steps; i++) {
        sequence.push(current);
        current /= 2;
    }
    
    return sequence;
}

console.log(halvingSequence(100, 4)); // [100, 50, 25, 12.5]
  • Módulo y asignación (%=):
let remainder: number = 17;
remainder %= 5; // Equivalente a: remainder = remainder % 5
console.log(remainder); // 2

// Uso práctico: alternar entre valores
function getTrafficLightColor(cycle: number): string {
    let state = cycle;
    state %= 3; // Ciclo entre 0, 1 y 2
    
    switch (state) {
        case 0: return "Red";
        case 1: return "Yellow";
        case 2: return "Green";
        default: return "Invalid";
    }
}

console.log(getTrafficLightColor(0)); // "Red"
console.log(getTrafficLightColor(5)); // "Green" (5 % 3 = 2)
  • **Exponenciación y asignación (**=)**:
let power: number = 2;
power **= 3; // Equivalente a: power = power ** 3
console.log(power); // 8 (2³)

// Ejemplo: crecimiento exponencial
function calculatePopulationGrowth(initial: number, growthRate: number, years: number): number {
    let population = initial;
    population **= (1 + growthRate * years);
    return Math.floor(population);
}

Operadores de asignación con bits

TypeScript también incluye operadores de asignación para operaciones a nivel de bits:

  • AND a nivel de bits y asignación (&=):
let flags: number = 0b1010; // Binario: 1010 (decimal: 10)
flags &= 0b1100; // AND con 1100, resultado: 1000
console.log(flags.toString(2)); // "1000" (decimal: 8)

// Uso práctico: desactivar un bit específico
function disableBit(value: number, position: number): number {
    const mask = ~(1 << position); // Crea una máscara con todos 1s excepto en position
    return value &= mask;
}

console.log(disableBit(0b1111, 1).toString(2)); // "1101"
  • OR a nivel de bits y asignación (|=):
let permissions: number = 0b0100; // Lectura
permissions |= 0b0010; // Añade permiso de escritura
console.log(permissions.toString(2)); // "0110"

// Ejemplo: configuración de flags
type UserPermissions = {
    canRead: boolean;
    canWrite: boolean;
    canDelete: boolean;
    canAdmin: boolean;
};

function permissionsToFlags(permissions: UserPermissions): number {
    let flags = 0;
    if (permissions.canRead) flags |= 0b0001;
    if (permissions.canWrite) flags |= 0b0010;
    if (permissions.canDelete) flags |= 0b0100;
    if (permissions.canAdmin) flags |= 0b1000;
    return flags;
}
  • XOR a nivel de bits y asignación (^=):
let toggle: number = 0b1010;
toggle ^= 0b1111; // XOR con 1111, invierte todos los bits
console.log(toggle.toString(2)); // "0101"

// Uso práctico: alternar un bit
function toggleBit(value: number, position: number): number {
    value ^= (1 << position);
    return value;
}

let state = 0b0000;
state = toggleBit(state, 2); // Activa el bit 2
console.log(state.toString(2)); // "0100"
state = toggleBit(state, 2); // Desactiva el bit 2
console.log(state.toString(2)); // "0000"

Operadores de desplazamiento y asignación

Estos operadores desplazan los bits y asignan el resultado:

// Desplazamiento a la izquierda (<<=)
let value: number = 5; // Binario: 101
value <<= 1; // Desplaza 1 bit a la izquierda: 1010
console.log(value); // 10

// Desplazamiento a la derecha (>>=)
let num: number = 16; // Binario: 10000
num >>= 2; // Desplaza 2 bits a la derecha: 100
console.log(num); // 4

// Desplazamiento a la derecha sin signo (>>>=)
let unsignedShift: number = -8;
unsignedShift >>>= 1; // Desplazamiento sin signo
console.log(unsignedShift); // Resultado positivo grande

Operadores de asignación lógica (ES2020+)

TypeScript soporta los operadores de asignación lógica introducidos en ES2020:

  • AND lógico y asignación (&&=):
let config = { debug: true };
// Solo asigna si el lado izquierdo es truthy
config.debug &&= false; // Equivalente a: if (config.debug) config.debug = false
console.log(config.debug); // false

// Ejemplo práctico
function updateUserSettings(settings: any): void {
    // Solo actualiza si la propiedad existe
    settings.notifications &&= { ...settings.notifications, email: false };
}
  • OR lógico y asignación (||=):
let username: string | null = null;
// Asigna solo si el lado izquierdo es falsy
username ||= "Guest"; // Equivalente a: username = username || "Guest"
console.log(username); // "Guest"

// Inicialización de propiedades
function ensureDefaults(options: any): void {
    options.timeout ||= 1000;
    options.retries ||= 3;
    options.cache ||= true;
}
  • Coalescencia nula y asignación (??=):
let count: number | null = null;
// Asigna solo si el lado izquierdo es null o undefined
count ??= 0; // Equivalente a: count = count ?? 0
console.log(count); // 0

// Con un valor definido
let quantity: number = 5;
quantity ??= 10; // No hace nada porque quantity ya tiene un valor
console.log(quantity); // 5

// Ejemplo: inicialización segura
function initializeCache(cache: Record<string, any> | null): Record<string, any> {
    cache ??= {};
    cache.lastAccess ??= Date.now();
    return cache;
}

Los operadores de asignación compuesta son herramientas valiosas para escribir código más conciso y expresivo. Permiten realizar operaciones comunes con menos código, manteniendo la claridad y reduciendo la posibilidad de errores al no tener que repetir variables.

Precedencia de operadores

La precedencia de operadores determina el orden en que se evalúan las expresiones en TypeScript. Entender este concepto es fundamental para escribir código predecible y evitar errores sutiles que pueden ser difíciles de detectar. Cuando una expresión contiene múltiples operadores, las reglas de precedencia dictan qué operaciones se ejecutan primero.

Tabla de precedencia

Los operadores en TypeScript se evalúan en el siguiente orden, de mayor a menor precedencia:

// De mayor precedencia (se evalúa primero) a menor precedencia (se evalúa después)
1. Agrupación ()
2. Acceso a miembros . []
3. Llamadas a funciones ()
4. Operadores de incremento/decremento ++ --
5. Operadores unarios + - ! ~ typeof void delete
6. Exponenciación **
7. Multiplicación, división, módulo * / %
8. Suma, resta + -
9. Desplazamiento de bits << >> >>>
10. Comparación < <= > >= instanceof in
11. Igualdad == != === !==
12. AND a nivel de bits &
13. XOR a nivel de bits ^
14. OR a nivel de bits |
15. AND lógico &&
16. OR lógico ||
17. Operador de coalescencia nula ??
18. Condicional (ternario) ? :
19. Asignación = += -= *= /= %= **= etc.
20. Coma ,

Ejemplos prácticos de precedencia

Veamos cómo la precedencia afecta la evaluación de expresiones:

// Ejemplo 1: Operaciones aritméticas
let result = 2 + 3 * 4;
console.log(result); // 14, no 20, porque * tiene mayor precedencia que +

// Ejemplo 2: Usando paréntesis para modificar la precedencia
let modifiedResult = (2 + 3) * 4;
console.log(modifiedResult); // 20, los paréntesis se evalúan primero

Operadores aritméticos y lógicos combinados

La combinación de operadores aritméticos y lógicos puede ser confusa:

// Sin conocer la precedencia, ¿qué valor tendrá esta expresión?
let complex = 5 + 10 > 3 * 5 && 10 % 3 === 1;

// Desglosando según precedencia:
// 1. 3 * 5 = 15 (multiplicación antes que suma y comparación)
// 2. 5 + 10 = 15 (suma antes que comparación)
// 3. 15 > 15 = false (comparación antes que AND lógico)
// 4. 10 % 3 = 1 (módulo antes que igualdad)
// 5. 1 === 1 = true (igualdad antes que AND lógico)
// 6. false && true = false (AND lógico al final)

console.log(complex); // false

Uso de paréntesis para claridad

Aunque conozcamos las reglas de precedencia, es recomendable usar paréntesis para hacer el código más legible:

// Versión más clara del ejemplo anterior
let clearComplex = ((5 + 10) > (3 * 5)) && ((10 % 3) === 1);
console.log(clearComplex); // false

// Otro ejemplo donde los paréntesis cambian el resultado
let a = 3;
let b = 4;
let c = 5;

// Sin paréntesis
let result1 = a + b * c;        // 3 + (4 * 5) = 3 + 20 = 23

// Con paréntesis
let result2 = (a + b) * c;      // (3 + 4) * 5 = 7 * 5 = 35

console.log(result1, result2);   // 23, 35

Precedencia en operadores de asignación

Los operadores de asignación tienen baja precedencia y se evalúan de derecha a izquierda:

let x: number;
let y: number;
let z: number;

// La asignación se evalúa de derecha a izquierda
x = y = z = 5;  // Primero z = 5, luego y = 5, finalmente x = 5

console.log(x, y, z);  // 5, 5, 5

// Combinando asignación con otros operadores
let a = 10;
let b = 5;

// La operación += tiene menor precedencia que *
a += b * 2;  // Equivale a: a = a + (b * 2) = 10 + 10 = 20

console.log(a);  // 20

Precedencia con operadores lógicos

La precedencia entre operadores lógicos es importante para entender cómo se evalúan las condiciones:

// AND (&&) tiene mayor precedencia que OR (||)
let condition = true || false && false;
// Se evalúa como: true || (false && false) = true || false = true

console.log(condition);  // true

// Usando paréntesis para cambiar la precedencia
let altCondition = (true || false) && false;
// Se evalúa como: (true || false) && false = true && false = false

console.log(altCondition);  // false

Operador de coalescencia nula (??) y su precedencia

El operador ?? tiene menor precedencia que la mayoría de los operadores, pero mayor que las asignaciones:

// ?? tiene menor precedencia que +
let value = null ?? 5 + 5;  // Se evalúa como: null ?? (5 + 5) = 10

console.log(value);  // 10

// ?? no se puede usar directamente con && o || sin paréntesis
// let invalid = null ?? true || false;  // Error de sintaxis

// Forma correcta con paréntesis
let valid = null ?? (true || false);
console.log(valid);  // true

Precedencia en expresiones condicionales

El operador ternario tiene baja precedencia, pero mayor que la asignación:

// El operador ternario se evalúa antes que la asignación
let status = true;
let message = status ? "Active" : "Inactive";

// Anidamiento de operadores ternarios
let score = 85;
let grade = score >= 90 ? "A" : score >= 80 ? "B" : score >= 70 ? "C" : "F";
console.log(grade);  // "B"

// Con paréntesis es más claro
let clearGrade = score >= 90 ? "A" : (score >= 80 ? "B" : (score >= 70 ? "C" : "F"));

Casos prácticos donde la precedencia importa

Operaciones bit a bit vs. lógicas

// AND bit a bit (&) vs. AND lógico (&&)
let flags = 5 & 3 && 7;  // Se evalúa como: (5 & 3) && 7 = 1 && 7 = true

// Con paréntesis para cambiar la precedencia
let altFlags = 5 & (3 && 7);  // Se evalúa como: 5 & 7 = 5

Operadores de comparación encadenados

// Esto NO funciona como en matemáticas
let value = 5;
let inRange = 1 < value < 10;  // Se evalúa como: (1 < value) < 10 = true < 10 = true

console.log(inRange);  // true, incluso si value fuera 15!

// Forma correcta
let properCheck = 1 < value && value < 10;
console.log(properCheck);  // true

Operadores unarios y su precedencia

let counter = 0;
let result = -++counter + 2;  // El incremento (++) se evalúa antes que la negación (-)
// Se evalúa como: -(++counter) + 2 = -1 + 2 = 1

console.log(result);  // 1

Buenas prácticas

  • Usa paréntesis para hacer explícita la precedencia deseada, incluso cuando no son estrictamente necesarios.
  • Divide expresiones complejas en variables intermedias con nombres descriptivos.
  • Evita depender de reglas de precedencia poco intuitivas.
  • Prioriza la legibilidad sobre la brevedad del código.
// En lugar de esto:
function isEligible(age: number, income: number, hasDebt: boolean): boolean {
    return age >= 18 && income > 30000 || age >= 65 && !hasDebt;
}

// Prefiere esto:
function isEligibleClear(age: number, income: number, hasDebt: boolean): boolean {
    const isWorkingAdult = age >= 18 && income > 30000;
    const isRetiredWithoutDebt = age >= 65 && !hasDebt;
    
    return isWorkingAdult || isRetiredWithoutDebt;
}

Entender la precedencia de operadores te permite escribir código más predecible y mantenible, evitando errores sutiles que pueden ser difíciles de detectar. Cuando tengas dudas, usa paréntesis para hacer explícita la intención y mejorar la legibilidad del código.

Aprende TypeScript online

Otros ejercicios de programación de TypeScript

Evalúa tus conocimientos de esta lección Operadores y expresiones con nuestros retos de programación de tipo Test, Puzzle, Código y Proyecto con VSCode, guiados por IA.

Funciones

TypeScript
Test

Reto composición de funciones

TypeScript
Código

Reto tipos especiales

TypeScript
Código

Reto tipos genéricos

TypeScript
Código

Módulos

TypeScript
Test

Polimorfismo

TypeScript
Código

Funciones TypeScript

TypeScript
Código

Interfaces

TypeScript
Puzzle

Funciones puras

TypeScript
Puzzle

Reto namespaces

TypeScript
Código

Funciones flecha

TypeScript
Puzzle

Polimorfismo

TypeScript
Test

Operadores

TypeScript
Test

Conversor de unidades

TypeScript
Proyecto

Funciones flecha

TypeScript
Test

Control de flujo

TypeScript
Código

Herencia

TypeScript
Puzzle

Clases

TypeScript
Puzzle

Proyecto validación de tipado

TypeScript
Proyecto

Clases y objetos

TypeScript
Código

Encapsulación

TypeScript
Test

Herencia

TypeScript
Test

Proyecto sistema de votación

TypeScript
Proyecto

Reto genéricos con clases

TypeScript
Código

Inmutabilidad

TypeScript
Puzzle

Interfaces

TypeScript
Test

Funciones de alto orden

TypeScript
Test

Reto map y filter

TypeScript
Código

Control de flujo

TypeScript
Test

Interfaces

TypeScript
Código

Reto funciones orden superior

TypeScript
Código

Herencia y clases abstractas

TypeScript
Código

Reto tipos mapped

TypeScript
Código

Herencia de clases

TypeScript
Código

Reto funciones puras

TypeScript
Código

Variables y constantes

TypeScript
Puzzle

Introducción a TypeScript

TypeScript
Test

Reto testing unitario

TypeScript
Código

Funciones de primera clase

TypeScript
Puzzle

Clases

TypeScript
Test

OOP y CRUD en TypeScript

TypeScript
Proyecto

Interfaces y su implementación

TypeScript
Código

Tipos genéricos

TypeScript
Test

Namespaces

TypeScript
Test

Operadores y expresiones

TypeScript
Código

Proyecto generador de contraseñas

TypeScript
Proyecto

Reto unión e intersección

TypeScript
Código

Encapsulación

TypeScript
Puzzle

Tipos de unión e intersección

TypeScript
Test

Tipos de unión e intersección

TypeScript
Puzzle

Reto hola mundo en TS

TypeScript
Código

Variables y constantes

TypeScript
Código

Funciones puras

TypeScript
Test

Control de flujo

TypeScript
Código

Introducción a TypeScript

TypeScript
Código

Resolución de módulos

TypeScript
Test

Control de flujo

TypeScript
Puzzle

Reto tipos de utilidad

TypeScript
Código

Reto tipos literales y condicionales

TypeScript
Código

Reto exportar e importar

TypeScript
Código

Propiedades y métodos

TypeScript
Código

Tipos de utilidad

TypeScript
Test

Clases y objetos

TypeScript
Código

Tipos de datos, variables y constantes

TypeScript
Código

Proyecto Minigestor de tareas

TypeScript
Proyecto

Operadores

TypeScript
Puzzle

Funciones flecha y contexto

TypeScript
Código

Proyecto Inventario de productos

TypeScript
Proyecto

Funciones

TypeScript
Puzzle

Reto type aliases

TypeScript
Código

Funciones de alto orden

TypeScript
Puzzle

Funciones y parámetros tipados

TypeScript
Código

Tipos literales

TypeScript
Puzzle

Reto enums

TypeScript
Código

Tipos de utilidad

TypeScript
Puzzle

Modificadores de acceso y encapsulación

TypeScript
Código

Polimorfismo

TypeScript
Puzzle

Tipos genéricos

TypeScript
Puzzle

Reto módulos

TypeScript
Código

Tipos literales

TypeScript
Test

Inmutabilidad

TypeScript
Test

Proyecto Generator de datos

TypeScript
Proyecto

Variables y constantes

TypeScript
Test

Funciones de primera clase

TypeScript
Test

Todas las lecciones de TypeScript

Accede a todas las lecciones de TypeScript y aprende con ejemplos prácticos de código y ejercicios de programación con IDE web sin instalar nada.

Introducción A Typescript

TypeScript

Introducción Y Entorno

Instalación Y Configuración De Typescript

TypeScript

Introducción Y Entorno

Tipos De Datos, Variables Y Constantes

TypeScript

Sintaxis

Operadores Y Expresiones

TypeScript

Sintaxis

Control De Flujo

TypeScript

Sintaxis

Funciones Y Parámetros Tipados

TypeScript

Sintaxis

Funciones Flecha Y Contexto

TypeScript

Sintaxis

Enums

TypeScript

Sintaxis

Type Aliases Y Aserciones De Tipo

TypeScript

Sintaxis

Clases Y Objetos

TypeScript

Programación Orientada A Objetos

Interfaces Y Su Implementación

TypeScript

Programación Orientada A Objetos

Modificadores De Acceso Y Encapsulación

TypeScript

Programación Orientada A Objetos

Herencia Y Clases Abstractas

TypeScript

Programación Orientada A Objetos

Polimorfismo

TypeScript

Programación Orientada A Objetos

Decoradores Básicos

TypeScript

Programación Orientada A Objetos

Propiedades Y Métodos

TypeScript

Programación Orientada A Objetos

Inmutabilidad

TypeScript

Programación Funcional

Funciones Puras Y Efectos Secundarios

TypeScript

Programación Funcional

Funciones De Primera Clase

TypeScript

Programación Funcional

Funciones De Alto Orden

TypeScript

Programación Funcional

Conceptos Básicos E Inmutabilidad

TypeScript

Programación Funcional

Funciones De Primera Clase Y Orden Superior

TypeScript

Programación Funcional

Composición De Funciones

TypeScript

Programación Funcional

Métodos Funcionales De Arrays (Map, Filter, Reduce)

TypeScript

Programación Funcional

Tipos Literales Y Tipos Condicionales

TypeScript

Tipos Intermedios Y Avanzados

Tipos Genéricos Básicos

TypeScript

Tipos Intermedios Y Avanzados

Tipos De Unión E Intersección

TypeScript

Tipos Intermedios Y Avanzados

Tipos De Utilidad (Partial, Required, Pick, Etc)

TypeScript

Tipos Intermedios Y Avanzados

Unknown, Never Y Tipos Especiales

TypeScript

Tipos Intermedios Y Avanzados

Tipos Mapped

TypeScript

Tipos Intermedios Y Avanzados

Genéricos Con Clases E Interfaces

TypeScript

Tipos Intermedios Y Avanzados

Módulos

TypeScript

Namespaces Y Módulos

Namespaces

TypeScript

Namespaces Y Módulos

Resolución De Módulos

TypeScript

Namespaces Y Módulos

Exportación E Importación De Módulos

TypeScript

Namespaces Y Módulos

Introducción A Módulos

TypeScript

Namespaces Y Módulos

Testing Unitario En Typescript

TypeScript

Testing

Accede GRATIS a TypeScript y certifícate

En esta lección

Objetivos de aprendizaje de esta lección

  1. Comprender los operadores aritméticos y cómo se utilizan para realizar operaciones matemáticas en TypeScript.
  2. Conocer los operadores de asignación y cómo se usan para asignar valores a variables.
  3. Entender los operadores de comparación y cómo se emplean para evaluar igualdad y desigualdad entre valores.
  4. Aprender los operadores lógicos y cómo se combinan condiciones para obtener resultados booleanos.
  5. Familiarizarse con los operadores de bits y su aplicación en operaciones a nivel de bits.
  6. Conocer el operador condicional (ternario) para asignar valores en función de condiciones.
  7. Aprender sobre los operadores typeof e instanceof para obtener información sobre tipos y verificaciones de instancia.