Implementación de Interfaces en TypeScript Paso a Paso
Resumen
La implementación de interfaces en TypeScript representa una herramienta poderosa que, aunque inicialmente puede parecer compleja, ofrece una flexibilidad extraordinaria en el desarrollo de aplicaciones. Las interfaces permiten definir estructuras de datos y comportamientos que pueden reutilizarse fácilmente, creando código más mantenible y escalable. Descubramos cómo aprovechar esta característica fundamental del lenguaje para mejorar nuestros proyectos.
¿Qué son las interfaces en TypeScript y por qué son tan flexibles?
Las interfaces en TypeScript son contratos que definen la estructura que debe tener un objeto o una función. A diferencia de las clases, las interfaces pueden extenderse con mayor facilidad y transferirse entre diferentes archivos, lo que las hace extremadamente versátiles.
Una de las principales ventajas de las interfaces es que permiten definir tanto propiedades como métodos, proporcionando una forma completa de modelar objetos y comportamientos. Esta característica las convierte en herramientas ideales para crear código reutilizable y bien estructurado.
Para implementar una interfaz básica en TypeScript, utilizamos la palabra reservada interface seguida del nombre que queremos asignarle:
Esta interfaz define que cualquier objeto de tipo Persona debe tener tres propiedades: nombre (string), edad (number) y esDesarrollador (boolean).
¿Cómo utilizar interfaces para objetos individuales?
Una vez definida una interfaz, podemos crear objetos que la implementen. Esto garantiza que dichos objetos cumplan con la estructura definida:
let persona:Persona={ nombre:"Juan", edad:30, esDesarrollador:true};console.log(persona);
Al ejecutar este código, veremos en la consola el objeto con las propiedades definidas. TypeScript verificará en tiempo de compilación que el objeto cumpla con la estructura de la interfaz, lo que ayuda a prevenir errores.
¿Cómo trabajar con colecciones de interfaces?
Las interfaces también pueden utilizarse para definir arreglos de objetos que comparten la misma estructura:
let personas:Persona[]=[{ nombre:"Juan", edad:30, esDesarrollador:true},{ nombre:"María", edad:25, esDesarrollador:false}];console.log(personas);
Este código crea un arreglo de objetos que implementan la interfaz Persona. Al ejecutarlo, veremos en la consola todos los elementos del arreglo.
¿Cómo definir métodos en interfaces?
Una característica poderosa de las interfaces es la capacidad de definir métodos que deben ser implementados por los objetos que las utilizan:
interfaceSumar{sumar(a:number, b:number):number;}let suma:Sumar={sumar(a:number, b:number):number{return a + b;}};console.log(suma.sumar(3,5));// Resultado: 8
En este ejemplo, la interfaz Sumar define un método llamado sumar que recibe dos parámetros numéricos y devuelve un número. Luego, creamos un objeto que implementa esta interfaz proporcionando la implementación del método.
¿Por qué usar interfaces para métodos?
Aunque puede parecer un poco burocrático definir métodos a través de interfaces, esta práctica ofrece varias ventajas:
Consistencia: Garantiza que todos los objetos que implementan la interfaz tengan los mismos métodos con las mismas firmas.
Documentación: Las interfaces actúan como documentación clara de lo que se espera de un objeto.
Flexibilidad: Diferentes clases u objetos pueden implementar la misma interfaz de distintas maneras.
¿Cómo combinar propiedades y métodos en interfaces?
Una de las grandes ventajas de las interfaces en TypeScript es que pueden combinar tanto propiedades como métodos en una misma definición:
Esta interfaz no solo define las propiedades de una persona, sino también métodos que pueden proporcionar información adicional sobre ella. Esta capacidad de combinar propiedades y comportamientos hace que las interfaces sean herramientas extremadamente versátiles.
Las interfaces en TypeScript son herramientas fundamentales que permiten crear código más estructurado, reutilizable y fácil de mantener. Aunque al principio pueden parecer complejas, una vez que se comprende su funcionamiento, se convierten en aliadas indispensables para el desarrollo de aplicaciones robustas. ¿Has utilizado interfaces en tus proyectos? Comparte tu experiencia y cómo han mejorado tu código en los comentarios.
en las interfaces no deberiamos agregar logica, creo que esa es la diferencia entre interface y clase, me equivoco?
Hola Ivan, pregunte a la IA que tiene platzi y me respondio lo siguente:
"Es correcto. La principal diferencia entre una interfaz y una clase en TypeScript es que las interfaces no deben contener lógica, solo definen la estructura de los objetos. Las clases, en cambio, pueden incluir tanto la estructura (a través de propiedades) como la lógica (métodos). Esto significa que las interfaces son ideales para definir contratos que las clases deben seguir sin implementar su funcionalidad, lo que permite mantener el código limpio y organizado."
Por ultimo, rectifique en otros medios de información y estas en lo correcto.
Gracias por la aclaración para un novato en TS <3
Esto aplica para cualquier lenguaje de programación.
Luego de un tiempo trabajando con typescript, creo que se creó una mala costumbre de como utilizar las interfaces.
En lo personal creo que cuando queremos tipar alguna estructura, ya sea un array o un objeto, lo correcto es utilizar type, y dejar las interfaces para OOP.
Estoy de acuerdo, hay que usar lo mejor de cada mundo, pero manteniendo la congruencia del propio.
Hola 👋 investigue un poco y encontre lo siguiente:
Regla general: Usar interface para objetos y type para todo lo demas.
Usar interface para:
Objetos y estructuras de datos (90% de los casos)
Herencia (extends)
Contratos para clases (implements)
APIs y modelos de datos
Declaration merging (librerías)
Usar type para:
Union types ('loading' | 'success' | 'error')
Aliases de primitivos (type ID = string)
Tipos de funciones (type Handler = (e: Event) => void)
Tipos computados/condicionales
Intersection types (A & B)
Template literals (/api/${string})
interfacePersona{nombre: string;edad: number;esDesarrollador: boolean;// Changed to optional saludar?:(saludo?: string)=>void;// Added a method signature}letpersona:Persona={nombre:"Leo",edad:25,esDesarrollador:true,saludar:function(saludo: string ="Hola"):void{console.log(`${saludo}${this.nombre}`);}}persona.saludar()console.log(persona);
La mejor práctica para nombrar archivos de interfaces en TypeScript es ser específico y seguir una convención clara. De las opciones dadas, interfaces.models.ts es la más adecuada si el archivo contiene interfaces relacionadas con modelos, ya que indica claramente su propósito.
Evita el uso de mayúsculas al comienzo del nombre (Interfaces.ts) y opta por mantener nombres en minúsculas para la consistencia. Utilizar interfaces.ts es válido, pero es menos específico que interfaces.models.ts. Por lo tanto, la convención más útil es interfaces.models.ts.
Al principio si es confuso entender las interfaces, sobre todo porque las veía muy parecidas a las clases, pero la gran diferencia es que en las interfaces no podemos agregar una implementación, solo definir como estructuramos los datos de la misma y su tipado. Por otro lado, si bien las clases también son como plantillas base, también podemos definir acciones que pueda realizar el objeto que sea una instancia de ella. Aparte de eso, las clases son como mas "reales" por así decirlo, ya que es código JS que entiende el entorno de ejecución.
lo poderoso de las interfases en POO es que permite el polimorfismo. En el ejemplo de Amin las esta usando como una simple clase.
interface Animal {
hacerSonido(): void;
}
class Perro implements Animal {
hacerSonido() {
console.log("Guau");
}
}
class Gato implements Animal {
hacerSonido() {
console.log("Miau");
}
}
function emitirSonido(a: Animal) {
a.hacerSonido();
}
emitirSonido(new Perro());
emitirSonido(new Gato());
Las interfaces y clases en TypeScript tienen propósitos diferentes.
Interfaces: Definen un contrato que las clases pueden implementar. Son útiles para establecer tipos sin necesidad de crear una instancia. Pueden extenderse, permitiendo una estructura flexible y reutilizable, como se menciona en el transcript. No pueden contener implementación de métodos.
Clases: Son plantillas para crear objetos y pueden contener tanto la definición de propiedades como la implementación de métodos. Las clases pueden extenderse, pero su enfoque es más sobre la creación de instancias y la encapsulación de datos y comportamientos.
Ambas son herramientas poderosas para estructurar el código, pero se utilizan en contextos distintos.
//intefaces con metodos
//las interfaces pueden definir metodos que los objetos deben implementar
//esto asegura que cualquier objeto que implemente la interfaz tenga esos metodos con las firmas correctas
//por ejemplo, una interfaz para un objeto que representa una calculadora
//la interfaz define un metodo sumar que toma dos numeros y devuelve un numero
//cualquier objeto que implemente esta interfaz debe proporcionar una implementacion para el metodo sumar
//esto ayuda a mantener la coherencia y la previsibilidad en el codigo
Las interfaces, enums y tipos literales en TypeScript tienen similitudes pero cumplen diferentes roles.
Interfaces: sirven para definir la forma de un objeto, describiendo sus propiedades y métodos. Son extensibles y permiten crear estructuras complejas.
Enums: son una forma de definir un conjunto de constantes relacionadas. Facilitan la lectura de código al usar nombres en lugar de valores numéricos o cadenas.
Tipos literales: permiten definir un tipo exacto para una variable o propiedad, restringiendo los valores a un conjunto específico.
Así, aunque comparten la capacidad de definir tipos, cada uno tiene un propósito distinto en la programación.
La implementación en las funciones es compleja de entender, dejo una explicación más profunda:
¿Para qué sirve esto?
Su propósito es definir un contrato o un molde, no para un objeto, sino para una función.
¿En qué casos se usa?
Se usa principalmente cuando las funciones son tratadas como "ciudadanos de primera clase", es decir, cuando se pasan como argumentos a otras funciones, se devuelven desde funciones o se asignan a variables.
¿Por qué hacerlo así?
Usas una interfaz "callable" para crear un contrato reutilizable para la firma de una función. Es ideal para callbacks y estrategias, y es especialmente poderosa para describir funciones que también se comportan como objetos con propiedades.