打字稿:推断类成员类型

时间:2021-03-25 13:50:56

标签: typescript generics conditional-types

我有两种类型,它们的成员是名为“action”的函数。动作函数的参数类型取决于类:

type Class_a = {
    action: (arg: string) => string
} 
type Class_b = {
    action: (arg: number) => string
}

我想要一个可以处理这两个类的类。为此,我定义了一个联合类型:

type EitherClass = Class_a | Class_b;

我有一个类型可以根据类推断参数类型(如本答案中所述:Have a Generic Type of a Method Depend on the Generic Type Of the Class in TypeScript

type ConditionalArg<T> = T extends Class_a ? string :
                         T extends Class_b ? number :
                         never;

但是,当我在另一个具有泛型类型的类中使用它时出现编译错误:

class MyClass<T extends EitherClass>
{
     public my_type: T;
     public my_arg: ConditionalArg<T>;

     public constructor(my_type: T, my_arg: ConditionalArg<T>)
     {
          this.my_type = my_type;
          this.my_arg = my_arg;
     }

     public do_action(): string
     {
          return this.my_type.action(this.my_arg); // Compile error here 
     }
} 

我收到以下错误: “ConditionalArg”类型的参数不可分配给“never”类型的参数。

调用构造函数时推理有效

let inst_a: Class_a = {action: (arg: string) => arg}
let inst_b: Class_b = {action: (arg: number) => arg.toString()}

let class_a_one = new MyClass(inst_a, "B") // compile
let class_a_two = new MyClass(inst_a, 3)  // do not compile
let class_b_one = new MyClass(inst_b, "B") // do not compile
let class_b_two = new MyClass(inst_b, 3) // compile

但是,推断在“do_action”方法中不起作用。是否有避免该错误的解决方法?

这是操场上的一个工作示例:Playground Link

1 个答案:

答案 0 :(得分:0)

我终于找到了解决方法。这个想法是在“do_action()”中转换“action”函数:

public do_action(): string
{
     let action = this.my_type.action as (arg: ConditionalArg<T>) => string
     return action(this.my_arg); // compile
}

操场上的工作示例:Playground link