Скажем, у меня есть такой объект:
export const v = {
a() : Promise<X>{
},
b() : Promise<Y>{
},
c() : Promise<Z>{
}
}
мой вопрос - есть ли способ получить тип v, но сопоставить тип, чтобы он выглядел примерно так:
export type V = {
a: X,
b: Y,
c: Z
}
в основном я сопоставляю каждый ключ объекта с разрешенным значением соответствующего обещания.
По сути, я пытаюсь получить модифицированный тип из того, что объявлено статически.






Вы можете сделать это, используя условные типы и сопоставленный тип:
class X{}
class Y{}
class Z{}
export const v = {
a() : Promise<X>{
return null as any;
},
b() : Promise<Y>{
return null as any;
},
c() : Promise<Z>{
return null as any;
},
}
type ExtractAllPromisses<T> =
{
// Take all keys of T ([P in keyof T])
// and if the property P of T is a promise returning function (T[P] extends ()=> Promise<infer U>)
// then the new type of P will be the return type of the promise (saved in U)
// Otherwise the new type of P is never
[P in keyof T]: T[P] extends ()=> Promise<infer U> ? U : never
};
export type V = ExtractAllPromisses<typeof v> // same as type V = { a: X; b: Y; c: Z; }
Есть варианты, которые вы можете сделать в условном типе в зависимости от ваших потребностей, приведенный выше пример работает специально для типа, который имеет только функции, которые не принимают аргументов и возвращают Promise.
Если вы хотите сопоставить функцию с любым количеством аргументов, вы можете использовать:
type ExtractAllPromisses<T> = { [P in keyof T]: T[P] extends (...args: any[])=> Promise<infer U> ? U : never };
Если у вашего типа также есть свойства, которые не обещают возвращаемые функции, и вы хотите сохранить эти свойства (например, v также имеет поле foo:number), вы можете использовать:
type ExtractAllPromisses<T> = { [P in keyof T]: T[P] extends (...args: any[])=> Promise<infer U> ? U : T[P] };
Если вы хотите исключить свойства, которые не являются функцией перенастройки обещаний. Вы можете отфильтровать ключи:
type PromiseFunctionFields<T> = { [P in keyof T] : T[P] extends (...args: any[])=> Promise<any> ? P : never}[keyof T];
type ExtractAllPromisses<T> = { [P in PromiseFunctionFields<T>]: T[P] extends (...args: any[])=> Promise<infer U> ? U : T[P] };