[英]How to use polymorphism with generics in Typescript?
If I have an object of type that take a generic T that extends another interface/type.如果我有一个类型的对象,它采用扩展另一个接口/类型的泛型 T。 How can I type an object/method param to allow any subtype generic.
如何键入对象/方法参数以允许任何子类型泛型。
An exemple will be easier to understand:举个例子会更容易理解:
type Options = {
id: string;
};
type Task<O extends Options = Options> = {
start: (options: O) => void;
};
const t1: Task<Options> = {
start: ({ id }) => {
console.log(id);
}
};
const t2: Task<{ id: "static"; foo: true } & Options> = {
start: ({ id, foo }) => {
console.log(id, foo);
}
};
const TaskManager = {
registerTask: (task: Task) => { // maybe I miss something here, I would like to avoid Task<any>
// use task
}
};
TaskManager.registerTask(t1); // Ok
TaskManager.registerTask(t2); // ERROR: Argument of type 'Task<{ id: "static"; foo: true; } & Options>' is not assignable to parameter of type 'Task<Options>'.
How can I modify registerTask to allow any Task
that accept Task<T extends Options>
如何修改registerTask允许任何
Task
接受Task<T extends Options>
Can someone help me to fix this typing issue ?有人可以帮我解决这个打字问题吗?
EDIT: Also, If TaskManager store an array of Task, how to type this array with generics ?编辑:另外,如果 TaskManager 存储一个 Task 数组,如何使用泛型键入这个数组?
class TaskManager {
private static tasks: Task[] = [];
public static registerTask = <O extends Options>(task: Task<O>) => {
TaskManager.tasks.push(task); // ERROR: Argument of type 'Task<O>' is not assignable to parameter of type 'Task<Options>'
};
}
I need to provide generic at class level ?我需要在类级别提供泛型?
Temporary solution is to declare an array of Task<any>
:临时解决方案是声明一个
Task<any>
数组:
private static tasks: Task<any>[] = [];
to allow any subtypes.允许任何子类型。
You can make TaskManager.registerTask()
a generic method like this:您可以使
TaskManager.registerTask()
成为这样的通用方法:
const TaskManager = {
registerTask: <O extends Options>(task: Task<O>) => {
}
};
which will then cause the compiler to infer O
when you call it:这将导致编译器在您调用它时推断
O
:
TaskManager.registerTask(t1); // okay
// (property) registerTask: <Options>(task: Task<Options>) => void
TaskManager.registerTask(t2); // okay
// (property) registerTask: <{ id: "static"; foo: true; } & Options>(
// task: Task<{ id: "static"; foo: true; } & Options>
// ) => void
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.