我目前面临 TypeScript 的问题,它似乎无法在涉及泛型、枚举和继承的特定场景中正确推断类型。
这是我的代码的简化版本:
enum Status {
UNDEFINED = 0,
SUCCESS = 1,
FAIL = 2,
}
class Result<StatusT extends Status = Status, Data = unknown, Code = string | number> {
constructor(
public status?: StatusT,
public data?: Data,
public code?: Code,
) {}
}
abstract class Task {
async done(...args: any[]) {
while (true) {
const result = await this.execute(...args);
if (result.status === Status.SUCCESS) {
return result;
}
}
}
abstract execute(...args: any[]): Promise<{
[K in Status]: Result<K>;
}[Status]>
}
class TestTask extends Task {
// (method) TestTask.execute(): Promise<Result<Status.SUCCESS, {}, number> | Result<Status.FAIL, string, string | number>>
async execute () {
if (Math.random() > 0.5) {
return new Result(Status.SUCCESS, {}, 0);
} else {
return new Result(Status.FAIL, "error");
}
}
}
const test = new TestTask()
// got: `Promise<Result<Status.SUCCESS, unknown, string | number>>`
// but i want: `Promise<Result<Status.SUCCESS, {}, number>>`
test.done();
TypeScript 仅将
done()
的返回类型推断为 Promise<Result<Status.SUCCESS, unknown, string | number>>
,而我希望它推断 Promise<Result<Status.SUCCESS, {}, number>>
。
为什么 TypeScript 无法按照我在 TestTask 类中的预期推断出特定的泛型类型?这是 TypeScript 类型推断系统的限制,还是我在如何注释或构造我的类型或代码方面遗漏了一些东西?
TypeScript 并没有让事物“假设地”通用 可能的子类。如果你想要这种行为,你需要写 自己找出多态类型,并使用类型断言。可能 如图所示在此游乐场链接中。
感谢@jcalz 的解释!