如何为返回给定输入或输入中包含的成员的TypeScript方法编写返回类型?
如果我有一个函数将返回提供的值(如果它不是容器)或容器内的值(如果提供的值是容器),我如何正确声明该函数的返回类型?例如:如何为返回给定输入或输入中包含的成员的TypeScript方法编写返回类型?,typescript,typescript-generics,Typescript,Typescript Generics,如果我有一个函数将返回提供的值(如果它不是容器)或容器内的值(如果提供的值是容器),我如何正确声明该函数的返回类型?例如: interface Container<TValue> { value: TValue; } declare function isContainer<TContained>( object: unknown ): object is Container<TContained>; type ContainedTypeOrIts
interface Container<TValue> {
value: TValue;
}
declare function isContainer<TContained>(
object: unknown
): object is Container<TContained>;
type ContainedTypeOrItself<T> = T extends Container<infer U> ? U : T
function getContainedValueOrSelf<T>(
input: T,
): ContainedTypeOrItself<T> {
if (isContainer<ContainedTypeOrItself<T>>(input)) {
return input.value
}
return input
}
因为我相信if
子句过滤了Container
类型的所有对象,所以我认为当代码到达返回输入
语句时,T
不是容器
,因此ContainedTypeOrItself
应该是自己键入的,T
。显然,考虑到编译器的错误,我对如何工作的理解是不正确的
在我的另一篇文章中,我了解了为什么在不小心使用any
的情况下使用三元运算符会导致与使用if-else
语句时不同的行为。然而,我仍然认为我太过密集,无法理解代码的实际错误,并且我已经多次阅读了那里的注释和答案。他们确实准确地回答了那里提出的问题:为什么三元运算符和if else
之间有不同的行为,对此我很感激——这正是我想要的。然而,在这个问题中,我使用了一个更简单的例子(谢谢!),并试图在键入时尽可能具体。我仍然很难理解为什么它不起作用,即使是在尝试应用关于任何用法、三元运算符以及使用该答案中的简化代码时
感谢您花时间阅读本文并提供帮助 我认为这是一个过度工程的例子。如果我没有正确理解,请注意我,我将删除我的答案
为什么我认为您的代码比它试图解决的看起来复杂得多?
如果您打算展平包含的对象,则展平函数的返回类型应始终为原始类型,T
使用expert
关键字会使您的解决方案复杂化,因此,如果要实现的目标是获得平面对象T
,请不要尝试返回除T
以外的任何其他类型
您的类型包含类型或自身将被描述为类似union的类型
type ContainedTypeOrItself<T> = Container<T> | T;
type ContainedTypeOrItself=Container | T;
然后,平坦函数将如下所示
const getContainedValueOrSelf = <T>(input: ContainedTypeOrItself<T>): T =>
isContainer<T>(input)
? input.value
: input;
const getContainedValueOrSelf=(输入:ContainedTypeOrItself):T=>
iContainer(输入)
? 输入值
:输入;
是的,三元运算得到了广泛的支持,编译器也完全理解
有几行显示了平坦的行为
const container: Container<number> = { value: 6 };
const decontained: number = getContainedValueOrSelf(container);
const raw: number = getContainedValueOrSelf(6);
const-container:container={value:6};
const decontained:number=getContainedValueOrSelf(容器);
const raw:number=getContainedValueOrSelf(6);
这让我怀疑,我试图回答的问题看起来比你的代码要简单得多。因此,如果我误解了您的问题,请警告我。这非常有效,肯定能解决问题。感谢您抽出时间阅读并回复!你的解决方案显然比我的简单。我想我仍然对为什么我的代码不起作用感到好奇(尽管可能过于复杂)——至少在我看来,这在理论上是正确的,但在您的示例中,您可以强制强制强制强制转换将输入作为containedTypeOritsef返回
并实现isContainer
函数,如return!!输入.value
(只要T
没有value
键)。
const container: Container<number> = { value: 6 };
const decontained: number = getContainedValueOrSelf(container);
const raw: number = getContainedValueOrSelf(6);