No tienes acceso a esta clase

隆Contin煤a aprendiendo! 脷nete y comienza a potenciar tu carrera

Partial y Required Type

18/22
Recursos

Los tipos Partial y Required en TypeScript son utility types que te permiten crear un nuevo tipo basado en un tipo existente, pero haciendo que todas las propiedades de ese tipo sean opcionales u obligatorias.

Partial type en TypeScript

Utilizamos la siguiente expresi贸n para definir un Partial type: Partial<T>. Esto genera un nuevo tipo que tiene todas las propiedades de T, pero cada atributo es opcional. Veamos un ejemplo:

interface User {
聽 id: number;
聽 name: string;
聽 email: string;
聽 phoneNumber: string;
}

// Usando `Partial` para hacer todas las propiedades de User opcionales
type PartialUser = Partial<User>;

// `PartialUser` es ahora un tipo con todas las propiedades de `User`, pero cada una de ellas es opcional.

let partialUser: PartialUser = {
聽 id: 1,
聽 name: 'Benjamin Hern谩ndez',
聽 // Podemos omitir `email` y `phoneNumber` ya que son opcionales en `PartialUser`
};

console.log(partialUser); // { id: 1, name: 'Benjamin Hern谩ndez' }

Hemos usado Partial para hacer que todas las propiedades de User sean opcionales. Por lo tanto, el nuevo tipo PartialUser tiene las propiedades id, name, email y phoneNumber, pero todas ellas son opcionales.

Required type en TypeScript

Empleamos la siguiente expresi贸n para definir un Required type: Required<T>. Esto genera un nuevo tipo que tiene todas las propiedades de T, pero cada atributo es obligatoria. Veamos un ejemplo:

interface User {
聽 id: number;
聽 name: string;
聽 email?: string;
聽 phoneNumber?: string;
}

// Usando `Required` para hacer todas las propiedades de User obligatorias
type RequiredUser = Required<User>;

// `RequiredUser` es ahora un tipo con todas las propiedades de `User`, pero cada una de ellas es obligatoria.

let requiredUser: RequiredUser = {
聽 id: 1,
聽 name: 'Fatima Fern谩ndez',
聽 email: '[email protected]',
聽 phoneNumber: '343-545-789'// No podemos omitir `email` y `phoneNumber` ya que son obligatorias en `RequiredUser`
};

console.log(requiredUser); // { id: 1, name: 'Fatima Fern谩ndez', email: '[email protected]', phoneNumber: '343-545-789' }

Hemos empleado Required para hacer que todas las propiedades de User sean obligatorias. Por lo tanto, el nuevo tipo RequiredUser tiene las propiedades id, name, email y phoneNumber, pero todas ellas son obligatorias.

Contribuci贸n creada por: Mart铆n 脕lvarez (Platzi Contributor).

Aportes 12

Preguntas 4

Ordenar por:

驴Quieres ver m谩s aportes, preguntas y respuestas de la comunidad?

Partial & Required en TS

Estos dos tipos de datos nos sirven para declarar que todos los campos de una interfaz son opcionales u obligatorios.

interface Product {
    title: string;
    price: number;
    category: string;
    size?: string;
}

type UpdateProduct = Partial<Product>
type StrictProduct = Required<Product>

De esa forma en UpdateProduct, todos los valores de Product van a ser opcionales y a la inversa en el caso de StrictProduct

Les comparto mis apuntes. 馃槃

Partial

Nos permite colocar todos los par谩metros de una interface como opcionales, sin necesidad que colocar ? par谩metro por par谩metro.

Sintaxis

interface InterfaceName extends Partial<Interface> {
		statements
}

type TypeName = Partial<TypeOrInterface>;

Required

Nos permite colocar todos los par谩metros de una interface como obligatorios.

Sintaxis

interface InterfaceName extends Required<Interface> {
		statements
}

type TypeName = Required<TypeOrInterface>;

Reutilizaci贸n de DTOs

Podemos reutilizar nuestro DTO normalmente, ya que son interfaces.

Ejemplo

import { Product } from "./product.model";

export interface CreateProductDto extends Omit<Product, 'id' | 'createdAt' | 'updatedAt' | 'category'> {
    categoryId: string;
}

export interface UpdateProductDto extends Partial<CreateProductDto> {

}

Tener en cuenta que cuando utilizamos CreateProductDTO tenemos omitidos el atributo updateAt que ser谩 necesario para el m茅todo de actualizar producto, en tonces al hacer lo siguiente:

export interface UpdateProductDTO extends Partial<CreateProductDTO> {}

estamos heredando la omisi贸n de updateAt y para recuperar esto podemos hacer una extenci贸n de m煤ltiple de lo que ten铆amos anteriormente m谩s el atributo updateAt que ser谩 necesario cuando actualicemos nuestro producto:

export interface UpdateProductDTO extends Partial<CreateProductDTO>, Pick<Product, 'updateAt'> {}

De verdad que el curso de manipulaci贸n de arrays debe estar genial. Es lo que tomar茅 al finalizar ac谩.

Nos sirven para declarar que los datos que provienen de ese tipo o interfaz son opcionales, usualmente lo usamos al momento de modificar datos.

Imagina que tienes un producto, este producto al momento de ser creado obtuvo ciertos datos, pero ahora necesitas modificarlo, sin embargo no necesitas todos los datos para modificarlo ya que solo modificaras o cambiaras ciertos datos.

Entonces all铆 entra Partials

interface Product {
	id: number,
	name: string,
	color: string,
	description: string,
	model: string,
	country: string,
}

interface EditProduct extends Product Partial<Product>

Required

A diferencia de Partials que pone todos los datos como opcionales, tenemos tambi茅n required que hace lo contrario, pone todos los datos como obligatorios.

Aprender todo esto de utility types me recuerda mucho a teor铆a de conjuntos, donde cada interface seria un conjunto y sus operaciones como intersecciones o uniones los utility types

Me he estado informando y creo que no hay una soluci贸n directa para convertir solo algunos campos opcionales en obligatorios utilizando Required y a la vez mantener el resto de atributos como est谩n. Sin embargo, he dado con un par de soluciones: ```js //Soluci贸n 1 export interface RequiredAttributes extends Required<Pick<CreateProductDto, 'size' | 'color'>>, Omit<CreateProductDto, 'size' | 'color'> {} //Soluci贸n 2 export interface RequiredAttributes extends Omit<CreateProductDto, 'size' | 'color'> { size: Sizes; color: string; } //Soluci贸n para "type" type RequiredType = Required<Pick<CreateProductDto, 'size' | 'color'>> & CreateProductDto; ```La primera soluci贸n consiste en extender de dos interfaces, una que recoge los atributos "size" y "color" y los convierte en atributos requeridos, y la otra interfaz que omite los campos "size" y "color". De esta forma en la nueva interfaz se har铆a una especie de uni贸n entre estas dos interfaces. En la segunda soluci贸n extendemos de la interfaz original, pero omitiendo los campos opcionales y volvi茅ndolos a a帽adir en la nueva interfaz, pero evitando que sean opcionales. La 煤ltima soluci贸n es pr谩cticamente como la primera pero aplicada a "type" en vez de a interfaces. 隆Espero que les sirva de ayuda! 馃挌 PD: he hecho opcional el campo "color" solo para este ejemplo.

en lugar del find puede ser un map.

const updateProduct = (id: string, payload: IUpdateProductDto) => {
    const updatedProducts = products.map(item => {
        return (item.id === id)? {...item, ...payload}: item
    })
    return updatedProducts
  }

En 8:52 Cuando se hace:

const prevData = productos[index]
products[index] = {
...prevData, ...changs
}

No es necesario el prevData, esta variable apunta al objeto en el array, no guarda una copia

Ya terminando la clase me perdi jejej
se confundio en el minuto 10

Lo que comentaba el profe sobre prevData y changes es muy importante en la vida real para no tener perdida de informaci贸n y no tener que restaurar un respaldo de la base de datos. Si algo as铆 te pasa y no tienes un respaldo鈥 estas en problemas.
Aqu铆 un peque帽o ejemplo de lo que menciona el profe con una API con Express:

router.put('/:ID', verify, async function (req, res) {
    try {
        const { ID } = req.params
        const clientesJSON = { ...req.body, ID }

        const item = await service.updateClientes(clientesJSON)
        res.json({
            message: 'Test api updated',
            item,
        })
    } catch (error) {
        res.status(404).json({ message: error.message })
    }
})

Podemos hacer que los campos sean opcionales con Partial

export interface UpdateProductDto extends Partial<CreateProductDto> {}

Y podemos hacer que sean obligatorios con Required

type example2 = Required<Product>