Tipos Avanzados
## Objetivos de Aprendizaje
- Dominar tipos mapeados
- Comprender tipos condicionales
- Usar tipos de literales de plantilla
- Crear tipos de utilidad
- Aplicar palabra clave infer
## Tipos Mapeados
### Sintaxis Basica
```typescript
type Readonly = {
readonly [P in keyof T]: T[P];
};
type Optional = {
[P in keyof T]?: T[P];
};
```
### Ejemplo: Todas las Propiedades Opcionales
```typescript
interface User {
id: number;
name: string;
email: string;
}
type PartialUser = Partial;
// { id?: number; name?: string; email?: string }
```
### Ejemplo: Todas las Propiedades Requeridas
```typescript
type Required = {
[P in keyof T]-?: T[P];
};
type RequiredUser = Required;
// Restaura todas las propiedades requeridas
```
## Tipo Record
### Crear Tipo de Objeto
```typescript
type Role = "admin" | "user" | "guest";
type Permissions = Record;
let perms: Permissions = {
admin: true,
user: false,
guest: true
};
```
### Record con Valores Complejos
```typescript
type EntityMap = Record;
let users: EntityMap = {
"user1": { id: 1, name: "Alice" },
"user2": { id: 2, name: "Bob" }
};
```
## Tipos Condicionales
### Sintaxis Basica de Tipos Condicionales
```typescript
T extends U ? X : Y
```
### Ejemplo
```typescript
type IsString = T extends string ? true : false;
type A = IsString; // true
type B = IsString; // false
```
### Con Union
```typescript
type ToArray = T extends any ? T[] : never;
type Strings = ToArray; // string[]
type Numbers = ToArray; // number[]
type Mixed = ToArray; // string[] | number[]
```
## Tipos Condicionales Distribuitivos
### Aplicados a Uniones
```typescript
type ToArray = T extends any ? T[] : never;
// string | number se convierte en string[] | number[]
type Result = ToArray;
// = string[] | number[]
```
### Prevenir Distribucion
```typescript
type ToArrayNonDist = [T] extends [any] ? T[] : never;
// Array unico: (string | number)[]
type Result = ToArrayNonDist;
```
## Palabra Clave infer
### Extraer Tipo
```typescript
type ReturnType = T extends (...args: any[]) => infer R ? R : never;
function getUser(): User {
return { name: "Alice" };
}
type R = ReturnType; // User
```
### Extraer Tipo de Elemento
```typescript
type ElementType = T extends (infer E)[] ? E : never;
type N = ElementType; // number
type S = ElementType; // string
```
## Tipos de Literales de Plantilla
### Basico
```typescript
type World = "world";
type Greeting = `hello ${World}`; // "hello world"
```
### Literales de Plantilla Con Union
```typescript
type Direction = "top" | "left";
type EventName = `on${Capitalize`;
// "onTop" | "onLeft"
```
### Plantillas Complejas
```typescript
type CSSProperty = "color" | "background";
type CSSValue = "red" | "blue";
type Rule = `${CSSProperty}: ${CSSValue}`;
// "color: red" | "color: blue" | "background: red" | "background: blue"
```
## Remapeo de Claves
### Clausula as
```typescript
type Getters = {
[P in keyof T as `get${Capitalize}`]: () => T[P]
};
interface User {
name: string;
age: number;
}
type UserGetters = Getters;
// { getName: () => string; getAge: () => number }
```
## Tipos de Utilidad en Profundidad
### Readonly
```typescript
type Readonly = {
readonly [P in keyof T]: T[P];
};
interface Config {
host: string;
port: number;
}
type ImmutableConfig = Readonly;
```
### Partial
```typescript
type Partial = {
[P in keyof T]?: T[P];
};
function updateUser(id: number, updates: Partial): void {
// updates puede tener cualquier subconjunto de propiedades de User
}
```
### Required
```typescript
type Required = {
[P in keyof T]-?: T[P];
};
// Elimina el marcador opcional
```
### Pick
```typescript
type Pick = {
[P in K]: T[P];
};
type UserPreview = Pick;
```
### Omit
```typescript
type Omit = Pick>;
type UserWithoutEmail = Omit;
```
### Exclude
```typescript
type Exclude = T extends U ? never : T;
type T = string | number | null;
type NonNullable = Exclude; // string | number
```
### Extract
```typescript
type Extract = T extends U ? T : never;
type T = string | number | boolean;
type Numeric = Extract; // string | number
```
### NonNullable
```typescript
type NonNullable = Exclude;
type T = string | null | undefined;
type U = NonNullable; // string
```
### ReturnType
```typescript
type ReturnType = T extends (...args: any[]) => infer R ? R : any;
function createUser() {
return { name: "Alice", age: 30 };
}
type User = ReturnType;
```
### Parameters
```typescript
type Parameters = T extends (...args: infer P) => any ? P : never;
function greet(name: string, age: number): string {
return `Hola ${name}`;
}
type GreetParams = Parameters; // [name: string, age: number]
```
## Tipos Recursivos
### Partial Profundo
```typescript
type DeepPartial = {
[P in keyof T]?: T[P] extends object ? DeepPartial : T[P];
};
interface Company {
name: string;
address: {
street: string;
city: string;
};
}
// Todas las propiedades anidadas opcionales
type OptionalCompany = DeepPartial;
```
## Tipos de Acceso Indexado
### Obtener Tipo de Propiedad
```typescript
type User = {
name: string;
age: number;
};
type Name = User["name"]; // string
```
### Acceso Indexado Con Union
```typescript
type User = {
name: string;
age: number;
email: string;
};
type NameOrEmail = User["name" | "email"]; // string
```
### keyof con Acceso Indexado
```typescript
type User = {
id: number;
name: string;
};
type UserKeys = User[keyof User]; // number | string
```
## Desenvolver Tipos
### Desenvolver Promise
```typescript
type Awaited = T extends Promise ? U : T;
type A = Awaited>; // string
type B = Awaited; // number
```
### Elemento de Array
```typescript
type ArrayElement = T extends (infer E)[] ? E : never;
type E = ArrayElement; // string
```
## Resumen
- Tipos mapeados: `[P in keyof T]` transforma propiedades
- Tipos condicionales: `T extends U ? X : Y`
- Literales de plantilla: `` `prefix${T}suffix` ``
- `infer` extrae tipos dentro de condicional
- Los tipos de utilidad usan tipos mapeados y condicionales
- `keyof` obtiene union de claves de objeto
- Tipos recursivos para transformaciones profundas
- Acceso indexado: `T["propiedad"]`
Comments
Comments powered by Giscus
To enable comments, add your Giscus embed code here.
Learn more about Giscus →