Tengo una función convert , su parámetro es un objeto, el valor puede ser una función o un objeto contiene tres propiedades, el tipo se ve así.
type Input = { [K: string]: () => any | { pending: () => any, fulfilled: () => any, rejected: {} => any } }Espero poder devolver un objeto, que las claves generarán por los valores, por ejemplo:
const result = convert({ sync() {}, async: { pending() {}, fulfilled() {}, rejected() {} } }); // the keys of result result.sync(); result.asyncPending(); result.asyncFulfilled(); result.asyncRejected();actualmente, sé cómo generar resultados mediante las claves y los literales de cadena
type Result<Input> = { [key in keyof Input as `${string & key}Fulfilled`]: any }pero no puedo cumplir con mi requisito, busco en Google durante mucho tiempo, pero no puedo encontrar la solución.
Mi solución propuesta se vería así:
type Input = { [key: string]: { pending: () => any, fulfilled: () => any, rejected: () => any } | (() => any) } type UnionToIntersection<U> = (U extends any ? (k: U)=>void : never) extends ((k: infer I)=>void) ? I : never type Result<Input> = { [K in keyof Input as Input[K] extends () => any ? K : never]: Input[K] } & UnionToIntersection<{ [K in keyof Input]: { [K2 in keyof Input[K] as `${K & string}${Capitalize<K2 & string>}`]: Input[K][K2] } }[keyof Input]> extends infer O ? { [K in keyof O]: O[K] } : never function convert<T extends Input>(arg: T): Result<T> { return {} as any } Para cada propiedad K de Input donde el tipo es un objeto, asignamos las claves en Input[K] . Para cada clave K2 dentro de Input[K] , cambiamos el nombre de la clave a ${K & string}${Capitalize<K2 & string>} y devolvemos el tipo Input[K][K2] . El objeto mapeado resultante se convierte en una unión indexándolo con keyof Input .
Esta unión se puede convertir en una intersección con UnionToIntersection para obtener todas las claves anidadas en un nivel superior.
Ahora el result tiene el tipo correcto:
const result = convert({ sync() {}, async: { pending() {}, fulfilled() {}, rejected() {} } }); // const result: { // sync: () => void; // asyncPending: () => void; // asyncFulfilled: () => void; // asyncRejected: () => void; // } result.sync(); result.asyncPending(); result.asyncFulfilled(); result.asyncRejected();