Estoy tratando de usar la función "seleccionar" de mecanografiado para obtener todos los valores posibles de mis objetos. Mis objetos tienen atributos opcionales, por lo que no necesariamente están configurados
const foo = [ { name: 'index', }, { name: 'id', type: 'number', }, { name: 'error', }, ] as const type ElementArg<T extends ReadonlyArray<unknown>> = T extends ReadonlyArray<infer ElementType> ? Pick<ElementType, 'name' | 'type'> : never type result = ElementArg<typeof foo> //result : {name: "index" | "id" | "error"} //expected : {name: "index" | "id" | "error" type: "number" | "undefined"}y también trato de convertir el atributo "tipo" en un tipo con:
type typeDecoder<T> = T extends 'number' ? number : T extends 'number[]' ? number[] : T extends 'string' ? string : T extends 'string[]' ? string[] : T extends 'boolean' ? boolean : T extends 'undefined' ? undefined : never;pero creo que hay una mejor manera de hacerlo y no sé dónde usar mi función
Me las arreglé para hacer que algo funcione:
type ElementArg<T extends ReadonlyArray<unknown>, R extends {} = {}> = T extends readonly [infer First, ...infer Rest] ? ElementArg<Rest, { [K in keyof First | keyof R]: K extends keyof R ? K extends keyof First ? R[K] | First[K] : R[K] | "undefined" : K extends keyof First ? First[K] : never }> : R;La idea principal es que recorremos cada uno de los elementos de la tupla y luego sumamos al resultado que acumulamos.
T extends readonly [infer First, ...infer Rest]Aquí obtenemos el primer elemento y el resto como una tupla. El siguiente es este gran trozo:
ElementArg<Rest, { [K in keyof First | keyof R]: K extends keyof R ? K extends keyof First ? R[K] | First[K] : R[K] | "undefined" : K extends keyof First ? First[K] : never }> Usamos ElementArg nuevamente en los elementos restantes, y luego el tipo mapeado largo y complicado agrega correctamente el contenido de este elemento a los resultados.
La lógica es así:
Para cada clave en el elemento o resultado
Si la clave es una clave del resultado
Si la clave es una clave del elemento
De lo contrario
"undefined" al resultadoO si la clave es una clave del elemento
Y finalmente, si el primer paso en el que intentamos obtener el primer elemento no funciona, eso significa que T está vacío y hemos terminado, por lo que devolvemos R .