gpt4 book ai didi

typescript - 如何在 Typescript 中使用泛型的多态性?

转载 作者:行者123 更新时间:2023-12-04 07:21:00 33 4
gpt4 key购买 nike

如果我有一个类型的对象,它采用扩展另一个接口(interface)/类型的通用 T。如何键入对象/方法参数以允许任何子类型泛型。
一个例子会更容易理解:

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>'.
如何修改 注册任务 允许任何 Task接受 Task<T extends Options>有人可以帮我解决这个打字问题吗?
编辑:
另外,如果 TaskManager 存储一个任务数组,如何用泛型键入这个数组?
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>'
};
}
我需要在类(class)级别提供通用信息吗?
临时解决方案是声明一个数组 Task<any> :
private static tasks: Task<any>[] = [];
允许任何子类型。

最佳答案

您可以制作TaskManager.registerTask()一个 generic像这样的方法:

const TaskManager = {
registerTask: <O extends Options>(task: Task<O>) => {

}
};
这将导致编译器推断 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
Playground link to code

关于typescript - 如何在 Typescript 中使用泛型的多态性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68501883/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com