0% encontró este documento útil (0 votos)
0 vistas15 páginas

Type Script

TypeScript es un superconjunto tipado de JavaScript que ayuda a detectar errores antes de la ejecución. Ofrece ventajas como la especificación de tipos y autocompletado en editores, mejorando la calidad del código. El documento detalla temas como tipos primitivos, inferencias, tipado de funciones, arrays y objetos tipados, así como el uso de interfaces y tipos para una mejor estructura y reutilización del código.
Derechos de autor
© All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
0 vistas15 páginas

Type Script

TypeScript es un superconjunto tipado de JavaScript que ayuda a detectar errores antes de la ejecución. Ofrece ventajas como la especificación de tipos y autocompletado en editores, mejorando la calidad del código. El documento detalla temas como tipos primitivos, inferencias, tipado de funciones, arrays y objetos tipados, así como el uso de interfaces y tipos para una mejor estructura y reutilización del código.
Derechos de autor
© All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd

TYPESCRIPT

-Es un superconjunto tipado de JavaScript


-El codigo que se escribe al final se ejecuta como JavaScript pero
TypeScript ayuda antes de ejecutar a detectar errores (en el editor y al
compilar)

VENTAJAS
-Permite especificar los tipos de los variables, parametros, valores de
retorno. Permite realizar comprobaciones durante la compilaciones y
detectar errores posibles cuando se escribe el codigo

-(Opinion personal) La principal ventaja es el autocompletado que vamos a


tener con VS

POTIPS
-Cuando pasamos algo a una funcion, si no definimos el tipo nos puede
arrojar una advertencia de que lo que estamos pasando pueda ser null,
entonces para eso podemos poner !, con esto garantizamos que lo que
estamos pasando no es null

-TypeScrip puede inferir en el tipo de nuestros datos, pero es mejor


crear grupos o interfaces

TEMA 1 - TIPOS PRIMITIVOS


-Son los tipos de datos de TS soporta de forma nativa como: number,
string, boolean, null, undefined

let const : string = "ciudad" //Ya despues si queremos modificar su valor


con otro valor de diferente tipo nos saldra error, TS infiere tipo
entonces en este caso no es necesario poner el tipo

-En JavaScript cualquier numero es un number


-undefined significa que no tiene aun valor asignado
-null significa que intencionalmente no tiene valor

LITERAL TYPE
-Con let TS inferiere un tipo generalmente primitivo, con un const este
no es el caso. EJM:

const estado = "activo"

-TS infiere el tipo como "activo" no string

UNION
-Es normal poner string | null, es decir que puede tener uno u otro tipo

BIGINT
let montoGrante : bigint = 100000000000n

TEMA 2 - INFERENCIAS

OBJETOS
const user = {
id: 1,
name: "Ana",
active: true
}

El tipo es: {id: number, name: string, active: boolean}


Por tanto [Link]="1" -> error

ARRAYS
const numbers = [1, 2 ,3]

tipo -> number[]


por tanto [Link]("1") //error

FUNCTIONS
-No existe inferencia aca, se debe tipar los parametros
-En Return si se infiere -> (): number

Regla de oro -> Dejar que TS infiera cuando pueda, y especificar cuando
no pueda o hay ambiguedad

TEMA 3 - TIPADO DE FUNCIONES


-Significa decir que tipo de datos recibe y que tipo de datos retorna
-Si no tipamos, los parametros son any, entonces -> sum("hola", true) ->
ERROR
-TypeScript infiera el tipo de retorno asi que es opcional tiparlo,
pero... ser explicito puede dar claridad y mantenimiento en un caso por
ejemplo donde se retorna lo de un fetch

Parametros opcionales

function greet(name?: string)


tipo: string | undefined

Tipar funciones flecha

const handleSubmit = (url: string) : void => fetch(url)

-Podemos tiparlo como variable


const handleSubmit : (url: string) => void = (url)=>fetch(url)

function login (email: string, password: string): boolean{


}

TEMA 4 - ARRAYS TIPADOS


-Es un array donde todos sus elementos tienen un tipo definido
-Con esto, TS cuida las cosas que puedes introducir en el
-Hay 2 formas de tiparlo:

FORMA 1: const numbers : number[] = [1,2,3]; //Mas usada

FORMA 2: const numbers : Array<number> = [1, 2, 3];


-Si se inicializa el array con valores, se infiere el tipo, pero si lo
iniciamos vacio -> any[] lo cual rompe la seguridad de tipos
-Mejor -> const saludos : string[] = [];

Arrays con objetos

interface User {
name: string,
city: string,
}

const users: User[] = [{}, {}]


-Ahora TS valida cada objeto del array
-Si bien TS infiere el tipo segun los valores, es mejor tiparlo desde un
inicio debido a que mantiene una estructura, es decir que si aumentamos
objetos, entonces se validara que dichos objetos cumplan la estructura

Arrays con Union Types


-Cuando un array puede tener mas de un tipo

const randoms : (string | number)[] = ["hola", 1, "gato"]

Arrays inmutables (solo lectura)


-readonly evita mutaciones, debe ir siempre antes de los tipos

const role : readonly string[] : ["admin", "user"];


-Por tanto no permite -> [Link]("invited"); X

TEMA 5 - OBJETOS TIPADOS


-Tipar un objeto significa definir exactamente que propiedades tiene y de
que tipo es cada una
-Formas de tipar:

Tipar inline

const user: {
name:string,
edad:number,
city?:string
} = {
name: "john",
number: 3
}

-Podemos poner una propiedad opcional con ?, equivale a city:string |


undefined
-Con readonly hacemos que el objeto sea inmutable

Objetos como parametros


function printUser (user : {name: string, old: number}, saludo:string) {
}
-Funciona pero no escala bien, para eso estan las interfaces

Objetos anidados
const order: {
id: number;
customer: {
name: string;
address: string;
};
} = {
id: 1,
customer: {
name: "Carlos",
address: "Av. Siempre Viva"
}
};

-Los errores comunes que nos ayuda a proteger tipar objetos es el exceso
de propiedades (datos inesperados)

FASE 2

TEMA 1: INTERFACE
-Es una forma de describir o definir la estructura de un objeto para
poder:
[Link]
[Link] nombre
[Link] en muchos lugares sin repetir codigo
-Se debe pensar una interface como un contrado (Cualquier objeto que diga
que es de este tipo, debe cumplir esta estructura)

Interfaces con propiedades null


-Cuando el dato existe pero puede ser vacio

interface Product {
id: number,
name: string,
discount: number | null
}
-Esto es distinto de ?, ? -> puede no venir, | null viene pero puede ser
null

Intefaces anidadas

inteface Address {
street:string,
city:string
}

interface User{
address:Address;
}

Readonly en interfaces
-Muy usado para IDs, datos de backend, props
interface User {
readonly id:number;
name:string;
}

[Link] = 5;

Errores comunes
-Usar interfaces para valores primitivos
-Usar any en interfaces

TEMA 2 - TYPE VS INTERFACE


-Ambos sirven para tipar objetos pero no son lo mismo
interface -> define la forma de un objeto
type -> crea un alias de tipo (puede ser muchas cosa)

Interface
-Ideal para objetos, props de React, Modelo de datos, APIs

Type
-Type permite Union Types |
type Status = "loading" | "success" | "error" //Esto no se permite con
interfaces

-Tambien permite Aliases:


type ID = string | number;

Extension o herencia
-Ambos son iguales pero interface es mas legible

inteface Admin extends User{}


type Admin = User & {}

-Type no permite hacer declaration mergin, es decir:


interface User{
id:number;
}

intefaces User{
name:string;
}
-Tenemos como resultado
interfaces User{
id:number;
name:string;
}

Regla practica
interfaces -> Objetos / props / modelos
type -> Unions / aliases / estados

EJEMPLO REAL:
interface User {
id: number;
name: string;
}
type UserStatus = "active" | "inactive";

TEMA 3 - UNION TYPES


-Un union type significa "esto puede ser uno u otro tipo", se usa con |
(OR logico de tipos)

let user : User | null = null

-Pero tiene sus limitaciones, por ejemplo:

function printId(id: number | string){


[Link](); //error
}
-Debemos de hacer validaciones con typeof si vamos a usar funciones que
solo funcionan en uno u otro tipo (esto se llama narrowing)

function printId(id: string | number) {


if (typeof id === "string") {
[Link]([Link]());
} else {
[Link]([Link](2));
}
}

Union en objetos
inteface ApiResponde {
data: User | null;
error: string | null;
}
-Esto nos ayuda a manejar exito y error

Discriminated Unions
-El siguiente patron es muy usado en React

type Result =
| {status: "success"; data: string}
| {status: "error"; message: string}

-Esto le dice a TS, Si status === "success" -> data existe

-Un ejemplo real de esto es lo siguiente:


type AuthState =
| { status: "logged_out" }
| { status: "logged_in"; userId: number };

-Esto es correcto pero lo siguiente no lo es:


interface AuthState {
status: "logged_out" | "logged_in";
userId?: number;
}

function handle(state: AuthState) {


if ([Link] === "logged_in") {
[Link](); // error
}
}

-En aca TS dice que use Id puede ser undefined ya que userId es opcion y
no existe ninguna relacion con el status "logged_in" como con el type
-Entonces cuando una propiedad depende de otra, usar Discriminated
Unions, no propiedades opcionales

TEMA 4 - PROPIEDADES OPCIONALES

Propiedad opcional ?
email?: string // Equivalente a :string | undefined

NULL

email: string | null


-Estamos diciendo que email siempre existe pero su valor puede ser null

COMBINARLOS

inteface User {
email?: string | null;
}
-Esto sucede mucho en apis mal diseñadas
-Cuando evaluamos un undefined en un contexto de boolean, entonces
obtemos un valor fasly (falso), por tanto cuando lo negamos con !,
obtenemos un true

ERROR COMUN
-Usar ? en lugar de null

interface Product {
discount?:number;
}
-Si el backend envia null, entonces habra un error

-Si el backend envia

interface Profile {
id:number;
bio?:string;
avatar: string | null;
}

FASE 3
TEMA 1 - TIPADO DE PROPS EN REACT
-Las props son datos que el component recibe deste fuera
-Se tipan las props para que el componente reciba solo lo que espera, si
hay alguna error, autocompletado

Forma correcta de tipar props


-Normalmente se tipan con interfaces (regla practica)
inteface ButtonProps {
label: string;
}

function Button ({label} : ButtonProps) {


return ...
}

Props con funciones (Muy comun)

interface ButtonProps {
label:string;
type: "success" | "error" | "warning";
onClick: (id:number) => void;
}

Props readonly (Buena practica)


-Los props no deben mutarse, si intentas modificar, TS te avisa

-Hay 2 formas de tipar props

const Card: [Link]<CardProps> = ({}) => {} // tipar la variable

-Hoy en dia no se recomiento usar [Link], sinos una forma mas moderna:

function Card({}:CardProps ){}

TEMA 2 - CHILDREN - [Link]


-children es todo lo que colocas entre las etiquetas de un componente
-Se lo tipa de la siguiente manera:
children: [Link];

-Es un tipo que representa todo lo que React puede renderizar, por
ejemplo: string, number, JSX, arrays de JSX, null, undifined, bool,
fragments

-Si el componente puede no tener contendio: children?: [Link];


-children: [Link]; Estaria mal ya que no permite string, array,
null, etc

TEMA 3 - USESTATE CON TYPESCRIPT

Caso 1: useState Simple (inferencia automatica)


const [count, setCount] = useState(0); // count : number
-Si el valor inicial es claro -> Dejar que infiera

Caso 2: Null
const [user, setUser] = useState<User | null>(null);
-Muy comun en apps reales

Caso 3: Arrays
const [users, setUsers] = useState([]); // Mal any[]
const [users, setUsers] = useState<User[]>[]);
-Se debe especificar explicitamente el tipo
Caso 4: Union State (Muy comun)
const [state, setState] = useState<"loading" | "error" |
"warning">("loading");

TEMA 4 - TIPADO DE EVENTOS EN REACT (MUY IMPORTANTE)


- Esto se usa todo el tiempo en: Forms, Inputs, Botones, Selects,
Textareas;
-Aca mucha gente termina usando any
-Un evento es una accion o suceso que ocurre en el navegador y que puede
ser detectado y manejado por el codigo
-React no usa directamente los eventos del DOM, sinos una capa propia, es
por eso que los eventos cambian un poco con el JS o HTML normal

EVENTOS COMUNES

ONCHANGE:
const handleChange = (e: [Link]<HTMLInputElement>) =>{}
-Es un evento de cambio, proviene de un input

const handleChange = (e: [Link]<HTMLTextAreaElement>) => {}

ONCLICK
const handleClick = (e: [Link]<HTMLButtonElement>) => {}

SUBMIT
const handleSubmit = (e: [Link]<HTMLFormElement>) => {}

-Quiza algo importante para acordarse es por ejemplo:


[Link]<OrigenEtiqueta>

-TS puede inferir el tipo del parametro e de la funcion pero unicamente


cuando no separamos la funcion (esta inline)
<input onChange={(e)=>{[Link]()}}/>

const handleClick = (e: [Link]<HTMLButtonElement>) => {}

-Como consejo se mejor usar currentTarget y no target porque target puede


ser un hijo interno y currentTarget siempre es el elemento donde esta el
handler

FASE 4

TEMA 1 - TIPADO DE RESPUESTAS DE API


const response = await fetch("");
const data = await [Link]();
-Cuando hacemos esto en react, data es de tipo any

Entonces haremos los siguientes pasos:

1. Modelar la respuesta
-Primero definimos el modelo o la interface

2. Tipamos la respuesta
const data : User = await [Link]();
const data : User[] = await [Link](); (Muy comun)

CASO PROFESIONAL (Response wrapper)


-Muchas APIs devuelven algo asi:
{
"data": [...],
"message": "ok",
"success": true
}

-Por tanto el modelo seria:


interface ApiResponse<T>{
data: T | null; //Null en caso de que el backend lo devuelva
message:string;
success: boolean;
}

-Y usamos de la siguiente forma:


const result : ApiResponse<User[]> = await [Link]();
-Y ahora [Link] // [Link]

TYPE ASSERTION
-Es decirle a TS: "Confia en mi. Yo se que tipo es esto" aunque TS no
pueda comprobarlo
-Es una forma de decirle a TS que trate un valor como un tipo especifico

const inputElement: HTMLInputElement | null =


[Link]('email')

const inputElement = [Link]('email') as


HTMLInputElement;

- Con el primer codigo se le dice a TS "Esta variable debe ser de este


tipo" pero saldra un error, ya que lo que retorna el getElementById es un
tipo generico HTMLElement | null
-En ese sentido hay veces donde el codigo retorna tipos genericos,
podemos usar esos tipos genericos pero perderemos la posibilidad de usar
las propiedades de los tipos especificos
-Es ahi donde entra el as. Si estamos seguros de lo que retorna algo,
podemos usar el type assertion para poder usar las propiedades
especificas
-Esta es una propiedad muy peligroso, pero se lo puede usar en el caso de
arriba y donde TS no pueda inferir el tipo correctamente

TEMA 2 - DTOs (Frontend vs Backend)


-DTO = Data Transfer Object
-Es un objeto que se usa para transportar datos entre diferentes partes
de una aplicacion o entre sistemas (frontend <-> backend, API <-> Base de
datos)
-El DTO es la estructura de datos que viaja entre dos capas

BENEFICIOS
-Seguridad: No se expone datos sensibles
-Desacoplamiento: Frontend y backend pueden tener estructuras diferentes
-Claridad: Se define exactamente que datos se transfieren

EL PROBLEMA:
-Supongamos que el backend retorna:
{
"id": 1,
"nombre_completo": "Juan Pérez",
"fecha_creacion": "2025-01-01T00:00:00.000Z"
}
-Pero el frontend trabaja o quiere trabajar asi:
{
id: number;
fullName: string;
createdAt: Date;
}
-Ahi es donde entra los DTOs

Paso 1: Modelar el DTO del backend


-Esto representa lo que exactamente viene del backend
interface UserDTO{
id:number;
nombre_completo:string;
}

Paso 2: Modelar el modelo interno


interface User {
id:number:
fullName: string;
}

Paso 3: Transformar
function mapUser(dto: UserDTO): User {
return {
id: [Link],
fullName: dto.nombre_completo,
createdAt: new Date(dto.fecha_creacion)
};
}

USO REAL:
const response = await fetch("/api/user/1");
const dto: UserDTO = await [Link]();
const user = mapUser(dto);

POR QUE NO USAR DIRECTAMENTE EL DTO?


-El backend puede cambiar de nombres
-Backend puede enviar strings donde tu quieres Date
-Backend puede usar snake_case
-Evita sobre todo acoplamiento fuerte
-Nunca debemos confiar en el backend como modelo interno
-Si el backend cambia algo, la UI explota

Tambien debemos realizar el proceso inverso


-El modelo interno puede NO coincidir con lo que el backend espera
-Por tanto se debe hacer un DTO de envio

function mapUserToDTO(user: User): CreateUserDTO {


return {
nombre_completo: [Link],
fecha_creacion: [Link]()
};
}

await fetch("/api/users", {
method: "POST",
body: [Link](mapUserToDTO(user))
});

-No es necesario usarlo si el frontend y backend usan exactamente el


mismo formato y el proyecto es pequeño
-Muchas APIs tienen: UserResponseDTO, CreateUserDTO, UpdateUserDTO
-Muchas veces se usa DTO = Mapper, entonces simplemente cuando alguien
hable de DTO, es mejor pensar en un mapper

ESTRUCTURA RECOMENDADA CUANDO SE TIENE DTO


src/
app/
routes/
providers/
store/ # si usas redux/zustand
shared/
api/
[Link] # fetch wrapper / axios instance
[Link]
types/
[Link] # ID, ISODateString, etc
utils/
features/
auth/
api/
[Link]
[Link] # LoginRequestDTO, LoginResponseDTO
[Link] # mapLoginResponseDTOToAuthSession
model/
[Link] # AuthSession, AuthState (interno)
components/
[Link]
hooks/
[Link]
users/
api/
[Link]
[Link] # UserDTO, CreateUserDTO, UpdateUserDTO
[Link] # mapUserDTOToUser, mapUserToCreateUserDTO
model/
[Link] # User (interno), UserStatus, etc
components/
[Link]
pages/
[Link]

TEMA 3 - OPTIONAL CHAINING


-Es un operador que nos permite acceder de forma segura a una propiedad o
funcion de un objeto
-Si intentamos acceder a una propiedad que no existe ocurrira error en
runtime: Cannot read property 'avatar' of undefined
-[Link]?.avatar // Si profile existe dame avatar, si no, devuelve
undefined sin romper la app

CASOS DE USO
return (
<div>
<img src={[Link]?.avatar} />
</div>
)
-Sin optional chaining si se romperia
-[Link]?.avatar?.length // Si alguno no existe dame undefined
-Ocurre el error cuando intentamos acceder a una propiedad de una
propiedad que no existe, no cuando simplemente acceder a esa propiedad
que no existe, en ese caso nos arrojara undefined

MUY IMPORTANTE
-Optional chaining no evita errores de tipo si TypeScript sabe que algo
puede ser null o undefined

VIEJA FORMA
-Se usaba [Link] && [Link]
-Es menos claro y no funciona igual con valroes falsy

TEMA 4 - NULLISH COALESCING


-Es un operador para poner un valor por defecto real
-Este operador casi siempre se usa junto con ?.
EJM:
<p>{user?.profile?.bio ?? "Sin biografía"}</p>
<img src={user?.profile?.avatar ?? "/[Link]"} />

FASE 5

TEMA 1 - GENERICS
-Un Generic es un tipo dinamico que se define al momento de usar la
funcion
-Resuelve el problema de construir una funcion igual pero que solo cambie
el tipo de dato
-Lo que causa repeticion y poca escalabilidad

function identity<T> (valor: T): T{


return valor;
}

indentity<string>("hola")
indentity<number>(1)

EN REACT
-UseState es un Generic, internamente esta escrito asi:
function useState<T>(initialValue : T) : [T, function]{}

CUANDO USAR?
-Cuando queremos que algo funcione con multiples tipos
-No queremos usar any

async function fetchData<T>(url: string): Promise<T> {


const response = await fetch(url)
return [Link]()
}

type User = {
id: number
name: string
}

const user = await fetchData<User>("/api/user")

TEMA 2 - UTILITY TYPES


-Los utility Types son tipos genericos ya construidos por TypeScript para
transformar otros tipos
-Los mas importantes son Partial, Pick, Omit

PROBLEMA:
type User = {
id: number
name: string
email: string
password: string
}
-Supongamos que cuando creamos un usuario no se tiene id, o cuando se
actuliza un usuario, no siempre envias todos los campos, o que no
queremos enviar password al frontend
-Crear un tipo para cada una de estas situaciones seria repetitivo y poco
mantenible

PARTIAL<T>
-Convierte todas las propiedades a opcionales
-Sin partial:
type UpdateUser = {
id?: number
name?: string
}

-Con partial:
type UpdateUser = Partial<User>

function updateUser(data: Partial<User>){} // Cuando hacemos un PATCH

PICK<T, K>
-Permite elegir solo ciertas propiedades
-Un caso real es para listar usuarios en una tabla
type UserListItem= Pick<User, "id" | "name", "email">

type UserPreview = {
id: number
name: string
email: string
}

OMIT<T, K>
-Hace lo contrario de Pick, elimina propiedades
-Un caso real es cuando se envia datos al frontend
function getUser(): Omit<User, "password">{
}
-Muy comun en DTOs frontend con Partial para updates parciales (PATCH)
type UpdateUserDTO = Partial<Omit<User, 'id'>>;

También podría gustarte