英文:
Return union of all possible function returns
问题
我想了解为什么这个代码会失败,编译器没有将A推断为类似于string[] | number[]
的联合类型。而是将A推断为第一个返回值,即string[]
。有没有办法修复这个问题?
const define = <A>({ handler }: { handler: (some: boolean) => A[] }) => ({ handler });
const a = define({
handler: (some: boolean) => {
if (some) {
return ["foo", "bar"];
} else {
return [1, 2];
}
},
});
英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论