例如 :
export const mock = <T>(provide, key: keyof T, value) => (){}
class Service {
do(): boolean {
return true;
}
}
// value have to be Boolean
mock<Service>(Service, "do", true)
value参数是T[key]
函数的返回类型。我想知道是否有可能以某种方式声明值的类型。
这是我的解决方案:
/**
* If T is a Class, return union string type of class methods
*/
type ClassType<T> = T extends { new(): infer R } ? keyof R : never
/**
* Check if property is a function/method
*/
type AnyFunc = (...args: any[]) => any
export const mock = <P,>(provide: P, key: ClassType<P>, value: P extends { new(): infer R } ? R[keyof R] extends AnyFunc ? ReturnType<R[keyof R]> : never : never) => {}
class Service {
do(): boolean {
return true;
}
}
const reuslt = mock<typeof Service>(Service, 'do', false) // ok
const reuslt2 = mock<typeof Service>(Service, 'foo', false) // error, expected do
const reuslt3 = mock<typeof Service>(Service, 'do', 42) // error, expected boolean
请记住,TS会以不同方式对待Service
类型typeof Service
。
因为我不是解释大师,所以这里是您的示例:
const x: Service = {
do: () => true
}
const y: typeof Service = class {
do() {
return true
}
}
TypeScript类文档
更新句柄承诺
/**
* If T is a Class, return union string type of class methods
*/
type ClassType<T> = T extends { new(): infer R } ? keyof R : never
/**
* Check if property is a function/method
*/
type AnyFunc = (...args: any[]) => any
type PromiseReturnType<T> = T extends Promise<infer R> ? R : T
export const mock = <P,>(provide: P, key: ClassType<P>, value: P extends { new(): infer R } ? R[keyof R] extends AnyFunc ? PromiseReturnType<ReturnType<R[keyof R]>> : never : never) => { }
class Service {
do() {
return new Promise<number>(resolve => resolve(42))
}
}
const reuslt = mock<typeof Service>(Service, 'do', false) // ok
const reuslt2 = mock<typeof Service>(Service, 'foo', false) // error, expected do
const reuslt3 = mock<typeof Service>(Service, 'do', Promise.resolve(42)) // error, expected number
const reuslt4 = mock<typeof Service>(Service, 'do', 42) // ok
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句