假设我有一个抽象类,它采用泛型
export abstract class RegisterableClass<InstanceType>
以及以下实施者:
class UserService extends RegisterableClass<IUserService> implements IUserService {
someConstant: 42,
async getAllUsers: (): User[] => {...}
}
具有如下接口:
interface IUserService {
someConstant: number;
getAllUsers: () => Promise<User[]>;
}
我想确保传递的泛型,IUserService
,在这种特殊情况下,都是异步的。
我可以以某种方式使用 TypeScript 静态执行此操作吗?
也许使用Extract<keyof IUserService, Function>
? 然后依次传递给某物?
也就是说,如果您尝试extend RegisterableClass
并传递给它一个并非所有函数都是异步的泛型,则打字稿将不会编译
理解正确,您希望将传递给RegisterableClass
的类型参数限制为方法都是异步的(意味着它们返回承诺(。
如果是这样,您可以像这样实现:
type AllMethodsAreAsync<I> = {
[K in keyof I]: I[K] extends (...args: any) => infer R ?
R extends Promise<any> ? I[K] : (...args: any) => Promise<R> :
I[K]
}
export abstract class RegisterableClass<I extends AllMethodsAreAsync<I>> {
// ... something involving I, hopefully
}
如果 I
是函数值属性返回 promise 的对象类型,则类型函数AllMethodsAreAsync<I>
将等效于 I
。 但是,如果I
具有任何不返回 promise 的函数值属性,则 AllMethodsAreAsync<I>
的相应属性将更改为返回 promise。
然后,如果I extends AllMethodsAreAsync<I>
传递了通用约束,那就太好了。 否则,您应该会收到一个错误,告诉您I
中的哪些内容不起作用。 喜欢这个:
// adding this so standalone example works
type User = { u: string };
interface IOkayService {
someConstant: number;
getAllUsers(): Promise<User[]>;
}
type OkayService = RegisterableClass<IOkayService>; // okay
interface IBadService {
someConstant: number;
getAllUsers(): Promise<User[]>;
getSomethingSynchronously(x: string): number;
}
type BadService = RegisterableClass<IBadService>; // error!
// ~~~~~~~~~~~
// Type 'IBadService' does not satisfy the constraint 'AllMethodsAreAsync<IBadService>'.
// Types of property 'getSomethingSynchronously' are incompatible.
// Type '(x: string) => number' is not assignable to type '(...args: any) => Promise<number>'.
// Type 'number' is not assignable to type 'Promise<number>'.
游乐场链接
这能做到你想要的吗? 希望有帮助;祝你好运!