[英]TypeScript conditional return type for generic function
I want to create a function which makes it easy to infer the structure of the run
method inside the task definition below.我想创建一个 function ,它可以很容易地在下面的任务定义中推断
run
方法的结构。 Is it possible to create a conditional return value so that inferTest1
has the type { skipped: boolean; result: number }
是否可以创建一个条件返回值,以便
inferTest1
具有类型{ skipped: boolean; result: number }
{ skipped: boolean; result: number }
and inferTest2
receives the type { skipped: boolean }
without a result property? { skipped: boolean; result: number }
和inferTest2
接收类型{ skipped: boolean }
没有结果属性?
interface TaskDefinition<T> {
run: () => { skipped: boolean } | { skipped: boolean; result: T };
}
function createTask<T>(
task: TaskDefinition<T>
): { skipped: boolean; result: T } | { skipped: boolean } {
const taskResult = task.run();
if ("result" in taskResult) {
return {
skipped: taskResult.skipped,
result: taskResult.result,
};
}
return {
skipped: taskResult.skipped,
};
}
const inferTest1 = createTask({
run: () => ({
skipped: false,
result: 251,
}),
});
const inferTest2 = createTask({
run: () => ({
skipped: false,
}),
});
I think the simplest solution here would be to use overloads:我认为这里最简单的解决方案是使用重载:
interface TaskDefinition<T> {
run: () => { skipped: boolean } | { skipped: boolean; result: T };
}
function createTask<T>(task: { run: () => { skipped: boolean; result: T } }): { skipped: boolean; result: T }
function createTask(task: { run: () => { skipped: boolean } }): { skipped: boolean }
function createTask<T>(task: TaskDefinition<T>): { skipped: boolean; result: T } | { skipped: boolean } {
const taskResult = task.run();
if ("result" in taskResult) {
return {
skipped: taskResult.skipped,
result: taskResult.result,
};
}
return {
skipped: taskResult.skipped,
};
}
const inferTest1 = createTask({
run: () => ({
skipped: false,
result: 251,
}),
});
inferTest1.result
const inferTest2 = createTask({
run: () => ({
skipped: false,
}),
});
inferTest2.result // err
You could also use conditional types, but I think that is overkill here.你也可以使用条件类型,但我认为这有点过分了。
Another solution would be to infer the result of run itself, although that might interfere with other things you are doing in the function:另一种解决方案是推断运行本身的结果,尽管这可能会干扰您在 function 中执行的其他操作:
function createTask<T extends { skipped: boolean } | { skipped: boolean; result: T }>(task: { run: () => T }): T {
const taskResult = task.run();
// Only spreading or type assertions will work to satisfy T, also narrowing is now borken
return {
...taskResult
};
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.