【发布时间】:2021-03-26 23:15:05
【问题描述】:
我有两种类型,它们的成员是一个名为“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
【问题讨论】:
-
以下是否足够好? typescriptlang.org/play?#code/…
-
确实有效。但是,就我而言,我无法修改 Class_a 和 Class_b,所以我无法将它们替换为使用泛型的类...
-
您不必修改 Class_a - 您可以依靠结构等价性(您的示例中是否显示了整个 class_a。不同的论点是否是 class_a 和 class_b 之间的唯一区别?)
-
不,class_a 有几个其他成员,class_b 也有。他们的成员有些是共同的,有些是不同的。
标签: typescript generics conditional-types