Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/visual-studio-code/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Typescript 为什么元组中的第一个值总是未知的?_Typescript_Visual Studio Code_Tuples_Typescript Generics - Fatal编程技术网

Typescript 为什么元组中的第一个值总是未知的?

Typescript 为什么元组中的第一个值总是未知的?,typescript,visual-studio-code,tuples,typescript-generics,Typescript,Visual Studio Code,Tuples,Typescript Generics,我的类型: 接口对{ 第一:()=>FirstValue, 第二:()=>SecondValue, toString:()=>字符串 } 类型StateRunner=(状态:S)=>Pair; 我的代码: constpair=(v1,v2):Pair=>({ 第一:()=>v1, 第二:()=>v2, toString:()=>`Pair(${v1},${v2})` }); constmyrunner:staterrunner=(state)=>Pair(“hello”,state); con

我的类型:

接口对{
第一:()=>FirstValue,
第二:()=>SecondValue,
toString:()=>字符串
}
类型StateRunner=(状态:S)=>Pair;
我的代码:

constpair=(v1,v2):Pair=>({
第一:()=>v1,
第二:()=>v2,
toString:()=>`Pair(${v1},${v2})`
});
constmyrunner:staterrunner=(state)=>Pair(“hello”,state);
const result=myRunner(someString,somesdata);
在VSCode中,我得到以下信息:

我100%肯定我只是不太了解泛型(我是TypeScript新手),但我认为它会将结果列为:


我错过了什么?我是否对TypeScript/VSCode期望过高?我感到困惑的主要原因是,当我直接使用
Pair
时,intellisense完全知道
first
second
的返回类型将是什么。

撇开不谈:我发现自己不得不修改您的示例代码,只是为了找到您的问题所在。示例:注释
v1
v2

const Pair = <V1, V2>(v1: V1, v2: V2): Pair<V1, V2> => ({
  first: () => v1,
  second: () => v2,
  toString: () => `Pair(${v1}, ${v2})`
});
我想这就是你的意思


代码的问题在于类型为
staterrunner
的函数声称能够获取调用者选择的泛型
S
值,并为调用者也选择的泛型
V
生成
对。那是不可能的,是吗?由于没有传入类型为
V
的值,因此没有合理的方式将输出作为
对。这种情况的一个症状是,当您让编译器推断调用者将指定的类型时,它完全不知道
V
将是什么。因此它推断出
未知


查看您的实现,您希望调用方选择
S
,实现者选择
V
。这意味着
V
S
不应该是同类泛型。我希望
staterrunner
本身是通用的,如下所示:

type StateRunner<V> = <S>(state: S) => Pair<V, S>;
const myRunner = asStateRunner((state) => Pair("hello", state));
// const myRunner: StateRunner<string>
现在一切正常了:

const r = myRunnerAnnotated({ a: "" }); // Pair<string, {a: string}>
然后像这样使用它:

type StateRunner<V> = <S>(state: S) => Pair<V, S>;
const myRunner = asStateRunner((state) => Pair("hello", state));
// const myRunner: StateRunner<string>

好的,希望这能给你一些指导。祝你好运


旁白:我发现自己不得不修改您的示例代码,以便找到您的问题所在。示例:注释
v1
v2

const Pair = <V1, V2>(v1: V1, v2: V2): Pair<V1, V2> => ({
  first: () => v1,
  second: () => v2,
  toString: () => `Pair(${v1}, ${v2})`
});
我想这就是你的意思


代码的问题在于类型为
staterrunner
的函数声称能够获取调用者选择的泛型
S
值,并为调用者也选择的泛型
V
生成
对。那是不可能的,是吗?由于没有传入类型为
V
的值,因此没有合理的方式将输出作为
对。这种情况的一个症状是,当您让编译器推断调用者将指定的类型时,它完全不知道
V
将是什么。因此它推断出
未知


查看您的实现,您希望调用方选择
S
,实现者选择
V
。这意味着
V
S
不应该是同类泛型。我希望
staterrunner
本身是通用的,如下所示:

type StateRunner<V> = <S>(state: S) => Pair<V, S>;
const myRunner = asStateRunner((state) => Pair("hello", state));
// const myRunner: StateRunner<string>
现在一切正常了:

const r = myRunnerAnnotated({ a: "" }); // Pair<string, {a: string}>
然后像这样使用它:

type StateRunner<V> = <S>(state: S) => Pair<V, S>;
const myRunner = asStateRunner((state) => Pair("hello", state));
// const myRunner: StateRunner<string>

好的,希望这能给你一些指导。祝你好运


除了他的答案,这里是@jcalz本人对TypeScript中泛型函数返回类型的一个彻底解释:)除了他的答案,这里是@jcalz本人对TypeScript中泛型函数返回类型的一个彻底解释:)对于那些将来偶然发现这个问题的人,我从中得到的最有价值的教训是,在函数名(例如myFunc)旁边声明的泛型是为实现者声明的,而在函数体旁边声明的泛型是为调用者声明的。这一点建议完全改变了我对打字脚本的理解。我不知道为什么在TypeScript手册中找不到这些信息。对于那些将来偶然发现这个问题的人来说,我从中得到的最有价值的教训是,函数名旁边声明的泛型(例如myFunc)是为实现者声明的,函数体旁边声明的泛型是为调用者声明的。这一点建议完全改变了我对打字脚本的理解。我不知道为什么我在TypeScript手册中找不到这些信息。