为啥我的元组中的第一个值总是未知的?
Posted
技术标签:
【中文标题】为啥我的元组中的第一个值总是未知的?【英文标题】:Why is the first value in my Tuple always unknown?为什么我的元组中的第一个值总是未知的? 【发布时间】:2020-10-03 12:06:15 【问题描述】:我的类型:
interface Pair<FirstValue, SecondValue>
first: () => FirstValue,
second: () => SecondValue,
toString: () => string
type StateRunner = <V, S>(state: S) => Pair<V, S>;
我的代码:
const Pair = <V1, V2>(v1, v2): Pair<V1, V2> => (
first: () => v1,
second: () => v2,
toString: () => `Pair($v1, $v2)`
);
const myRunner: StateRunner = (state) => Pair("hello", state);
const result = myRunner(someString, someData);
在 VSCode 中,我得到了这个:
我 100% 肯定我只是不太了解泛型(我是 TypeScript 的新手),但我认为它会将结果列为:
Pair<string,
size: string,
active: boolean
>
我错过了什么?我是否对 TypeScript/VSCode 期望过高?我感到困惑的主要原因是,当我直接使用Pair
时,智能感知完全知道first
和second
的返回类型是什么。
【问题讨论】:
除了他的回答之外,这里是@jcalz本人对TypeScript ***.com/a/60179671/795876中泛型函数的返回类型的详尽解释:) 【参考方案1】:除此之外:我发现自己必须更改您的示例代码才能到达您的问题所在的位置。示例:注释v1
和v2
:
const Pair = <V1, V2>(v1: V1, v2: V2): Pair<V1, V2> => (
first: () => v1,
second: () => v2,
toString: () => `Pair($v1, $v2)`
);
而myRunner
只接受一个参数:
const result = myRunner( a: "" );
我想这就是你的意思。
您的代码的问题是StateRunner
类型的函数声称能够获取调用者选择的泛型类型S
的值,并为泛型类型V
生成Pair<V, S>
由调用者选择。这是不可能的,是吗?由于没有传入V
类型的值,因此没有合理的方式输出Pair<V, S>
。这种情况的一个症状是,当您让编译器推断调用者将指定的类型时,它完全不知道V
将是什么。所以它推断unknown
。
查看您的实现,您希望调用者选择S
,而实现者选择V
。这意味着V
和S
不应该是同类的泛型。我希望StateRunner
本身是通用的,如下所示:
type StateRunner<V> = <S>(state: S) => Pair<V, S>;
所以V
是StateRunner
类型的一部分,由实现者选择,S
是通用函数类型的一部分,由调用者选择。而且你不会有StateRunner
类型的值;对于特定的V
,您将拥有StateRunner<V>
类型的值。对于myRunner
,它将是StateRunner<string>
:
const myRunnerAnnotated: StateRunner<string> = state => Pair("hello", state);
现在一切正常:
const r = myRunnerAnnotated( a: "" ); // Pair<string, a: string>
如果您不想手动将某些内容注释为StateRunner<string>
,您可以使用辅助函数为您推断V
:
const asStateRunner = <V>(s: StateRunner<V>) => s;
并像这样使用它:
const myRunner = asStateRunner((state) => Pair("hello", state));
// const myRunner: StateRunner<string>
您可以看到myRunner
被推断为StateRunner<string>
,然后result
像以前一样按照您想要的方式工作:
const result = myRunner( a: "" ); // Pair<string, a: string>
好的,希望对您有所帮助。祝你好运!
Playground link to code
【讨论】:
对于那些将来偶然发现这个问题的人来说,我从中学到的最有价值的一课是在函数名旁边声明的泛型(例如,myFunc以上是关于为啥我的元组中的第一个值总是未知的?的主要内容,如果未能解决你的问题,请参考以下文章
从Haskell中的元组中提取第n个元素(其中n和元组被赋予参数)
我的元组中的那些小“u”是啥? (python 2.7)[重复]