英文:
Return union of all possible function returns
问题
我想了解为什么会失败,编译器没有将A推断为类似于`string[] | number[]`的联合类型。相反,A被推断为第一个返回值,在这种情况下是`string[]`。有办法修复吗?
英文:
I would like to understand why this fails and the compiler does not infer A as a union like string[] | number[]
. instead A is inferred as the first return value, in this case string[]
. Is there a way to fix it?
const define = <A>({ handler }: { handler: (some: boolean) => A[] }) => ({ handler });
const a = define({
handler: (some: boolean) => {
if (some) {
return ["foo", "bar"];
} else {
return [1, 2];
}
},
});
答案1
得分: 0
这是因为当TypeScript扫描您的代码时,它遇到了这个语句 -
if (some) {
return ["foo", "bar"];
}
然后它继续尝试急切地推断泛型的类型,因为它是一个普通的泛型(没有任何约束),所以它将其确定为该类型,当它继续扫描时,它发现您返回了一个数字数组,因此它返回到函数定义并看到泛型类型已经确定,并抛出错误。
您可以像这样克服这个问题 -
const define = <A extends Array<unknown>>({ handler }: { handler: (some: boolean) => A }) => ({ handler });
const a = define({
handler: (some: boolean) => {
if (some) {
return ["foo", "bar"];
} else {
return [1, 2];
}
},
});
这里是一个Playground链接。
英文:
This happens because when Typescript is scanning your code, it comes across statement -
if (some) {
return ["foo", "bar"];
}
And it goes ahead and tries to infer the type for the generic eagerly, because it's a plain generic (without any sort of constraint), it exacts it to that type, and when it continues to scan, it finds you returning a an array of numbers, so it goes back to check the function definition and sees that the generic type has already been determined, and throws an error.
You can overcome it like this -
const define = <A extends Array<unknown>,>({ handler }: { handler: (some: boolean) => A }) => ({ handler });
const a = define({
handler: (some: boolean) => {
if (some) {
return ["foo", "bar"];
} else {
return [1, 2];
}
},
});
Here's a Playground link.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论