Búsqueda de sitios web

javascript - Cómo implementar deep pick en typescript


Me gustaría implementar deep pick en TypeScript.

Mi código de ejemplo es:

interface TestBook {
    id: string;
    name: string;
}
interface TestUser {
    id: string;
    email: string;
    books: TestBook[];
}

Yo y yo gustaría usar selección profunda como:

const foo: DeepPick<TestUser, 'id' | 'books.name'> = {...
/*

{
  id: ..
  books: [{name: ...}]
}

*/

Problema: Solo existe Pick en TypeScript estándar y no hay ninguna biblioteca que implemente este DeepPick.

¿Cómo puedo hacerlo? ¿Qué técnica debería usar?

Intenté buscar en Google y SO.

Respuesta #1

Primero definamos algunos tipos de utilidad para obtener la "cabeza" o la "cola" de una ruta:

type Head<T extends string> = T extends `${infer First}.${string}` ? First : T;

type Tail<T extends string> = T extends `${string}.${infer Rest}` ? Rest : never;

Luego, nuestro DeepPick puede tomar las cabezas de los caminos y luego seleccionar profundamente la cola:

type DeepPick<T, K extends string> = T extends object ? {
  [P in Head<K> & keyof T]: T[P] extends readonly unknown[] ? DeepPick<T[P][number], Tail<Extract<K, `${P}.${string}`>>>[] : DeepPick<T[P], Tail<Extract<K, `${P}.${string}`>>>
} : T

Si no es un objeto, no deberíamos hacerle nada. Dentro del tipo mapeado, también añadí un caso para los arrays.

Parque infantil

Artículos relacionados