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ícateOperadores 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í?
- Ve que la variable
a
es declarada comostring
. - Ve que la variable
b
es declarada comonumber
. - Ve que estás intentando usar el operador
>
para comparara
yb
.
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?
- Tomas el valor de
a
(que es unstring
). - Usas
Number(a)
. Esto es una conversión explícita. Le estás diciendo a TypeScript: "Toma el valor del stringa
e inténtalo convertir en su representación numérica". - El resultado de
Number(a)
será unnumber
(si la conversión fue exitosa) oNaN
(Not a Number, si el string no representaba un número válido, como "hola"). - Ahora la comparación es entre el resultado de
Number(a)
(que es unnumber
) yb
(que también es unnumber
). Estás comparando dosnumber
.
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.
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
Reto composición de funciones
Reto tipos especiales
Reto tipos genéricos
Módulos
Polimorfismo
Funciones TypeScript
Interfaces
Funciones puras
Reto namespaces
Funciones flecha
Polimorfismo
Operadores
Conversor de unidades
Funciones flecha
Control de flujo
Herencia
Clases
Proyecto validación de tipado
Clases y objetos
Encapsulación
Herencia
Proyecto sistema de votación
Reto genéricos con clases
Inmutabilidad
Interfaces
Funciones de alto orden
Reto map y filter
Control de flujo
Interfaces
Reto funciones orden superior
Herencia y clases abstractas
Reto tipos mapped
Herencia de clases
Reto funciones puras
Variables y constantes
Introducción a TypeScript
Reto testing unitario
Funciones de primera clase
Clases
OOP y CRUD en TypeScript
Interfaces y su implementación
Tipos genéricos
Namespaces
Operadores y expresiones
Proyecto generador de contraseñas
Reto unión e intersección
Encapsulación
Tipos de unión e intersección
Tipos de unión e intersección
Reto hola mundo en TS
Variables y constantes
Funciones puras
Control de flujo
Introducción a TypeScript
Resolución de módulos
Control de flujo
Reto tipos de utilidad
Reto tipos literales y condicionales
Reto exportar e importar
Propiedades y métodos
Tipos de utilidad
Clases y objetos
Tipos de datos, variables y constantes
Proyecto Minigestor de tareas
Operadores
Funciones flecha y contexto
Proyecto Inventario de productos
Funciones
Reto type aliases
Funciones de alto orden
Funciones y parámetros tipados
Tipos literales
Reto enums
Tipos de utilidad
Modificadores de acceso y encapsulación
Polimorfismo
Tipos genéricos
Reto módulos
Tipos literales
Inmutabilidad
Proyecto Generator de datos
Variables y constantes
Funciones de primera clase
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
Introducción Y Entorno
Instalación Y Configuración De Typescript
Introducción Y Entorno
Tipos De Datos, Variables Y Constantes
Sintaxis
Operadores Y Expresiones
Sintaxis
Control De Flujo
Sintaxis
Funciones Y Parámetros Tipados
Sintaxis
Funciones Flecha Y Contexto
Sintaxis
Enums
Sintaxis
Type Aliases Y Aserciones De Tipo
Sintaxis
Clases Y Objetos
Programación Orientada A Objetos
Interfaces Y Su Implementación
Programación Orientada A Objetos
Modificadores De Acceso Y Encapsulación
Programación Orientada A Objetos
Herencia Y Clases Abstractas
Programación Orientada A Objetos
Polimorfismo
Programación Orientada A Objetos
Decoradores Básicos
Programación Orientada A Objetos
Propiedades Y Métodos
Programación Orientada A Objetos
Inmutabilidad
Programación Funcional
Funciones Puras Y Efectos Secundarios
Programación Funcional
Funciones De Primera Clase
Programación Funcional
Funciones De Alto Orden
Programación Funcional
Conceptos Básicos E Inmutabilidad
Programación Funcional
Funciones De Primera Clase Y Orden Superior
Programación Funcional
Composición De Funciones
Programación Funcional
Métodos Funcionales De Arrays (Map, Filter, Reduce)
Programación Funcional
Tipos Literales Y Tipos Condicionales
Tipos Intermedios Y Avanzados
Tipos Genéricos Básicos
Tipos Intermedios Y Avanzados
Tipos De Unión E Intersección
Tipos Intermedios Y Avanzados
Tipos De Utilidad (Partial, Required, Pick, Etc)
Tipos Intermedios Y Avanzados
Unknown, Never Y Tipos Especiales
Tipos Intermedios Y Avanzados
Tipos Mapped
Tipos Intermedios Y Avanzados
Genéricos Con Clases E Interfaces
Tipos Intermedios Y Avanzados
Módulos
Namespaces Y Módulos
Namespaces
Namespaces Y Módulos
Resolución De Módulos
Namespaces Y Módulos
Exportación E Importación De Módulos
Namespaces Y Módulos
Introducción A Módulos
Namespaces Y Módulos
Testing Unitario En Typescript
Testing
En esta lección
Objetivos de aprendizaje de esta lección
- Comprender los operadores aritméticos y cómo se utilizan para realizar operaciones matemáticas en TypeScript.
- Conocer los operadores de asignación y cómo se usan para asignar valores a variables.
- Entender los operadores de comparación y cómo se emplean para evaluar igualdad y desigualdad entre valores.
- Aprender los operadores lógicos y cómo se combinan condiciones para obtener resultados booleanos.
- Familiarizarse con los operadores de bits y su aplicación en operaciones a nivel de bits.
- Conocer el operador condicional (ternario) para asignar valores en función de condiciones.
- Aprender sobre los operadores
typeof
einstanceof
para obtener información sobre tipos y verificaciones de instancia.