Búsqueda de sitios web

TypeScript - eliminar todas las propiedades con un tipo particular


Tengo un type que se utiliza para proyectar las claves presentes en T a las claves comunes y los tipos de las mismas presentes en U:

type IntersectByCommonKey<T, U, V = any> = {
  [K in keyof U]: K extends keyof T ?
  T[K] extends V ?
  U[K]
  : T[K] extends object ?
  IntersectByCommonKey<T[K], U[K], V>
  : T[K] extends object | undefined ?
  IntersectByCommonKey<T[K], U[K], V> | undefined
  : never
  : never
};

Enlace del Playground IntersectByCommonKey

donde para cada clave K en U, si T tiene la misma clave K, y si el tipo en K extiende V, incluye la forma para esa clave, de lo contrario nunca.

Con el tipo devuelto por IntersectByCommonKey quiero eliminar cada clave que tenga un tipo never, lo que significa que también debe manejar formas de Record anidadas.

Es bastante fácil eliminar las claves de nivel superior:

type ExcludeKeysWithTypeOf<T, V> = {
  [K in keyof T]: Exclude<T[K], undefined> extends V ? never : K 
}[keyof T]

type Without<T, V> = Pick<T, ExcludeKeysWithTypeOf<T, V>>;

ExcluirClavesConTipoDe Enlace de Playground

Sin embargo, me está costando lograr el mismo resultado para Records anidados, ¿hay alguna manera de que pueda eliminar recursivamente las claves con tipos never?

Respuesta #1

Necesitamos hacer una llamada recursiva para entrar en tipos de registros anidados. Aquí hay un ejemplo de solución:

type Without<T, V, WithNevers = {
  [K in keyof T]: Exclude<T[K], undefined> extends V ? never 
  : (T[K] extends Record<string, unknown> ? Without<T[K], V> : T[K])
}> = Pick<WithNevers, {
  [K in keyof WithNevers]: WithNevers[K] extends never ? never : K
}[keyof WithNevers]>

La idea principal es que cuando nuestro T[K] tenga tipo de Record, se llamará recursivamente a sí mismo (función a nivel de tipo Without). Todo el tipo se reducirá a la forma deseada en la que cada objeto anidado tendrá eliminadas las claves que queríamos.

Todo el fragmento de código - el área de pruebas

Nota: Moví el cálculo de WithNevers dentro de la lista de argumentos del tipo para lograr una mejor legibilidad. También podemos definirlo como un tipo separado.

Artículos relacionados