我试图弄清楚如何返回用于链接API的推断参数类型。下面是一个简化的示例:
type NoInfer<T> = [T][T extends unknown ? 0 : never]
interface Alpha<Foo extends string> {
foo: Foo
bar: `Depends on ${NoInfer<Foo>}`
}
interface Chain<ACC> {
bravo: <T extends { [K in keyof T]: string }>(xs: { [K in keyof T]: Alpha<T[K]> }) => void
// instead of void, return Chain<[***inferred type of xs***, ...ACC> -------------^^^^
}
在上面的例子中,bravo
参数类型工作得很好,但是缺少通过链构建类型上下文的能力。如何在每次调用bravo
时将推断出的xs
类型捕获到返回类型中,并递归地传递给泛型类型Chain
?
Playground链接
注意,我发现返回类型为{ [K in keyof T]: Alpha<T[K]> }
似乎是可行的。TS似乎有这样的行为,即给定的输入(参数)将决定返回位置的类型。
然而,彻底的复制充其量是很难阅读,维护等,有没有一个解决方案,不走这条路?
1条答案
按热度按时间bt1cpqcv1#
您真正想要的是创建内联类型别名,如microsoft/TypeScript#30979中所述。不幸的是,该功能不是该语言的一部分。如果是,那么也许我可以告诉您编写
然后继续前进。如果没有这样的功能,我所能给予你的就是变通方法。
最普遍适用的解决方法是只创建一个实用程序类型;也就是说,常规类型别名位于所需位置之外:
然后在需要的地方多次使用它:
这需要比你想要的多一点的代码,但是你在做什么是显而易见的。而且,如果类型是你实际上需要多次的东西,给予它一个有意义的名字可能是值得的(
MapAlpha
对于mapsAlpha
在对象类型上似乎是合理的)。作为第二种方法:如果在作用域中有一个你想要的类型的值,你可以使用the
typeof
operator来引用它的类型。即使该值是一个函数参数,这也会起作用:这里
typeof xs
与{ [K in keyof T]: Alpha<T[K]> }
相同。这更简洁,但可能会让读者感到有点困惑。但主要问题是,并不总是可以直接找到所需类型的值,您可能不得不退回到实用程序类型定义。
有时候还有其他的解决方法,包括在更大的范围内使用额外的类型参数来充当内联类型别名,但是对于给定的示例,我无法提出任何我想要建议的东西。我的意思是,下面的排序工作:
但是它依赖于
U
从xs
中推断出来,而T
是从xs
中推断出来的,因此类型不一定相同。Playground链接到代码