英文:
Guarded type, still not assignable
问题
我的输出类型取决于输入类型。我使用自定义守卫来保护输入,但仍然无法分配给声明的输出类型:
type InputType<Sub extends SubType> = { a: Sub, b: string }
type SubType = Sub1 | Sub2
type Sub1 = { a: string }
type Sub2 = { a: string, b: string }
type OutputType<Sub extends SubType> =
Sub extends Sub2 ?
{ c: string, d: string } :
{ c: string }
function handle<Sub extends SubType>(mainType: InputType<Sub>): OutputType<Sub> {
if (hasSub2(mainType)) {
return {c: '', d: ''};
} else {
return {c: ''};
}
}
function hasSub2(a: InputType<SubType>): a is InputType<Sub2> {
return 'b' in a.a;
}
英文:
My out type depends on the input type. I'm guarding the input with custom guard, but it's still not assignable to declared output:
type InputType<Sub extends SubType> = { a: Sub, b: string }
type SubType = Sub1 | Sub2
type Sub1 = { a: string }
type Sub2 = { a: string, b: string }
type OutputType<Sub extends SubType> =
Sub extends Sub2 ?
{ c: string, d: string } :
{ c: string }
function handle<Sub extends SubType>(mainType: InputType<Sub>): OutputType<Sub> {
if (hasSub2(mainType)) {
return {c: '', d: ''};
} else {
return {c: ''};
}
}
function hasSub2(a: InputType<SubType>): a is InputType<Sub2> {
return 'b' in a.a;
}
答案1
得分: 1
以下是翻译好的部分:
目前的 TypeScript 设计限制是函数返回表达式必须可分配给显式的未解决条件返回类型注释,控制流的缩小不会帮助解决这个问题(问题)。
在 handle
中的 {c: '', d: ''}
和 {c: ''}
不能分配给未解决条件的返回类型 OutputType<Sub>
。你可以采取以下措施:
替代方案 2 的实现
function handle<Sub extends SubType>(mainType: InputType<Sub>): OutputType<Sub>
function handle(mainType: InputType<SubType>): OutputType<SubType> {
if ('b' in mainType.a) {
return { c: '', d: '' };
} else {
return { c: '' };
}
}
const sub1Res = handle({ a: { a: "aa" }, b: "b" }) // {c: string; }
const sub2Res = handle({ a: { a: "aa", b: "ab" }, b: "b" }) // { c: string; d: string; }
这样,函数的调用方可以获得正确的返回类型,函数的实现方(调用方或实现方)现在也可以编译。
2: https://www.typescriptlang.org/play/#code/C4TwDgpgBAkgdmArsAKuCAeAyogRlCAD2AjgBMBnKHXNSAPigF4oBvKAQwC5q8AaKLh4VgAJwCWcAOZQAvgFgAUKEi9a6ZmoCMUAD5qATEpXQaOlu25QRE6XOMaaBzZeFjJUgUOvu7C5RoA8shIqOjYeATEpJRqdBCMTEpQalEk5FROUAD8ySlsUADGbraeUGQlHnJQXHkp7MU+pfaKSgBmiHCFwOIA9nBQABYc5AA2mDRpMZl48fQAFAC2HJLxPPCh8RG49ACUPMHAm+E0jKx54m1Q88MUTksrcPG7u2x1UKIQwIiiA6yNAHIAQIKlAgbJOFRDsdINt6ABuPIQiCjCjQc6KfIfL4-P6AgEQjhQkLILanRGYlr+dqdbp9Aa3e5WDakk6zdB7HgcKDiKgssKwpxnPKfb6-MG4AE8gYcAB0HAp-iAA 3: https://www.typescriptlang.org/play/?ssl=17&ssc=2&pln=10&pc=1#code/C4TwDgpgBAkgdmArsAKuCAeAyogRlCAD2AjgBMBnKHXNSAPigF4oBvKAQwC5q8AaKLh4VgAJwCWcAOZQAvgFgAUKEi9a6ZmoCMUAD5qATEpXQaOlu25QRE6XOMaaBzZeFjJUgUOvu7C5RoA8shIqOjYeATEpJRqdBCMTEpQalEk5FROUAD8yWxQAMZutp5QZMUeclBceexFPiX2ikoAZohwBcDiAPZwUAAWHOQANpg0aTGZePH0ABQAthyS8TzwofERuPQAlDzBwOvhNPSt7Z09fYMjEAtLcCuwCMgbNDO7UPuHkJszbHniLSgswA5LhgVBJFBFst0AA6DjbP6KFIpUQQYCIUR9Oo8YHAgTlKB4uQAbjysgIwwo0FYeVR6Mx2MKuPBsjJyKa-iUBV6ImseC0ACUIFQWFcyKNZq58lYAEQcDiyuReHiy3BK2SIgD0WrY9RsHhJTR5cD5FDwBmFooGQwlN2l0vlipVUHl6uVglV7s1UB1+X1vikRsJBukRtkQA
英文:
A current TS design limitation is that function return expressions must be assignable to the explicit unresolved conditional return type annotation, narrowing with the control flow doesn't help (issue).
{c: '', d: ''}
and {c: ''}
in handle
are not assignable to the unresolved conditional return type OutputType<Sub>
. You can do the following:
- cast all return expressions to
OutputType<Sub>
(sample) - create a separate function overload (sample)
Implementation of alternative 2
function handle<Sub extends SubType>(mainType: InputType<Sub>): OutputType<Sub>
function handle(mainType: InputType<SubType>): OutputType<SubType> {
if ('b' in mainType.a) {
return { c: '', d: '' };
} else {
return { c: '' };
}
}
const sub1Res = handle({ a: { a: "aa" }, b: "b" }) // {c: string; }
const sub2Res = handle({ a: { a: "aa", b: "ab" }, b: "b" }) // { c: string; d: string; }
This way, the caller of the function gets the right return type and also the body of the function (callee or implementation side) compiles now.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论