具有 return 类型的所有 class 方法名称的通用类型
Generic type for all class methods names with return type
我正在尝试创建一个泛型,它将为我提供有关所有 class 方法 return 类型(+ 字段,但它们并不那么重要)的信息。
假设我创建了这样一个 class:
class TestClass {
testField: string;
constructor() {
this.testField = 'test';
}
testMethod1(param: number): number {
return param;
}
testMethod2(param: string): string {
return param;
}
}
结果,我想要这样的类型:
interface TestClassMethodsNamesReturnType {
testMethod1: number;
testMethod2: string;
}
到目前为止我尝试了什么
映射类型+类型推断:
示例 1
export type ClassMethodsNamesReturnType<T extends Function> = {
[k in keyof T['prototype']]: ReturnType<T['prototype'][k]>;
}
const x: ClassMethodsNamesReturnType<TestClass> = {
//...
}
错误:
Type 'TestClass' is missing the following properties from type 'Function': apply, call, bind, prototype, and 5 more
映射类型并将class视为对象:
示例 2
// I think here I can have problems to decide is the key of my class is a field or method
// what can be a problematic to decide what I should use (typeof T[K] or ReturnType<typeof T[K]>)
export type ClassMethodsNamesReturnType<T extends Record<string, T[K]>, K extends keyof T> = {
[K]: T[K];
}
错误:
A computed property name in a type literal must refer to an expression whose type is a literal type or a 'unique symbol' type
'K' only refers to a type, but is being used as a value here
你有什么提示或想法我怎样才能做到这一点?
虽然您需要使用映射类型中的 as
子句进行条件筛选,但您可以通过映射类型执行此操作。然后,检查该值是否扩展 Function
然后 return never
如果没有,那么它不会被映射。这是完整的代码:
class TestClass {
testField: string;
constructor() {
this.testField = 'test';
}
testMethod1(param: number): number {
return param;
}
testMethod2(param: string): string {
return param;
}
}
type FnReturns<T> = { [K in keyof T as T[K] extends Function ? K : never]: ReturnType<T[K] extends (...args: any[]) => any ? T[K] : never> };
// Correctly passes:
const foo: FnReturns<InstanceType<typeof TestClass>> = {
testMethod1: 23,
testMethod2: "hey",
}
// correctly fails:
const fail: FnReturns<InstanceType<typeof TestClass>> = {}
另请注意我如何使用 typeof TestClass
的 InstanceType
来获取 TestClass
.
的实例方法和属性
我正在尝试创建一个泛型,它将为我提供有关所有 class 方法 return 类型(+ 字段,但它们并不那么重要)的信息。
假设我创建了这样一个 class:
class TestClass {
testField: string;
constructor() {
this.testField = 'test';
}
testMethod1(param: number): number {
return param;
}
testMethod2(param: string): string {
return param;
}
}
结果,我想要这样的类型:
interface TestClassMethodsNamesReturnType {
testMethod1: number;
testMethod2: string;
}
到目前为止我尝试了什么
映射类型+类型推断:
示例 1
export type ClassMethodsNamesReturnType<T extends Function> = { [k in keyof T['prototype']]: ReturnType<T['prototype'][k]>; } const x: ClassMethodsNamesReturnType<TestClass> = { //... }
错误:
Type 'TestClass' is missing the following properties from type 'Function': apply, call, bind, prototype, and 5 more
映射类型并将class视为对象:
示例 2
// I think here I can have problems to decide is the key of my class is a field or method // what can be a problematic to decide what I should use (typeof T[K] or ReturnType<typeof T[K]>) export type ClassMethodsNamesReturnType<T extends Record<string, T[K]>, K extends keyof T> = { [K]: T[K]; }
错误:
A computed property name in a type literal must refer to an expression whose type is a literal type or a 'unique symbol' type
'K' only refers to a type, but is being used as a value here
你有什么提示或想法我怎样才能做到这一点?
虽然您需要使用映射类型中的 as
子句进行条件筛选,但您可以通过映射类型执行此操作。然后,检查该值是否扩展 Function
然后 return never
如果没有,那么它不会被映射。这是完整的代码:
class TestClass {
testField: string;
constructor() {
this.testField = 'test';
}
testMethod1(param: number): number {
return param;
}
testMethod2(param: string): string {
return param;
}
}
type FnReturns<T> = { [K in keyof T as T[K] extends Function ? K : never]: ReturnType<T[K] extends (...args: any[]) => any ? T[K] : never> };
// Correctly passes:
const foo: FnReturns<InstanceType<typeof TestClass>> = {
testMethod1: 23,
testMethod2: "hey",
}
// correctly fails:
const fail: FnReturns<InstanceType<typeof TestClass>> = {}
另请注意我如何使用 typeof TestClass
的 InstanceType
来获取 TestClass
.