Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/399.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
Javascript 为什么可以';t Typescript是否为可选参数推断函数参数类型?_Javascript_Typescript - Fatal编程技术网

Javascript 为什么可以';t Typescript是否为可选参数推断函数参数类型?

Javascript 为什么可以';t Typescript是否为可选参数推断函数参数类型?,javascript,typescript,Javascript,Typescript,我认为试穿更清晰: 函数标识任意>(fn:T):T{ 返回fn; } 函数fn(参数:{ cb:(foo:number)=>无效, }) {} fn({ cb:identity((foo/*推断数字*/)=>{}), }); 函数fn2(参数:{ cb?:(foo:number)=>无效, }) {} fn2({ cb:identity((foo/*不推断数字*/)=>{}), }); 功能fn3(参数:{ cb:(foo:number)=>无效, } | {}) {} fn3({ cb:ide

我认为试穿更清晰:

函数标识任意>(fn:T):T{
返回fn;
}
函数fn(参数:{
cb:(foo:number)=>无效,
}) {}
fn({
cb:identity((foo/*推断数字*/)=>{}),
});
函数fn2(参数:{
cb?:(foo:number)=>无效,
}) {}
fn2({
cb:identity((foo/*不推断数字*/)=>{}),
});
功能fn3(参数:{
cb:(foo:number)=>无效,
} | {}) {}
fn3({
cb:identity((foo/*推断数字*/)=>{}),
});
对于
fn
fn3
,TS能够推断
foo
是一个
数字。但是,对于
fn2
,TS只是将
foo
键入为
any
fn2
fn3
的类型在功能上是相同的,所以我想知道为什么TS不能推断
foo
的类型

这方面的实际用例是React的
useCallback
,我试图推断通过
useCallback
的函数的参数类型


为什么TS会这样做?有没有一个不太老套的解决方案?

问题是,在
fn2
中,
cb
arg是
可选的
,因此
标识
无法从中推断。因此,您希望显式地告诉TS,arg可以是未定义的,如下所示:

function fn2(args: {
  cb: (foo: number) => void | undefined
}) {}
这应该会起作用,并使推断再次起作用


我认为这里的关键步骤是推断
身份
的返回类型:

 let result: ((foo: number) => void | undefined) = identity(...);
由于返回类型的基本约束为
(…args:any[])=>any
,因此Typescript规范的此规则适用于:

每个类型参数的推断类型参数是为该类型参数进行的推断集的联合类型。但是,如果联合类型不满足类型参数的约束,则推断的类型参数将改为约束

~

由于
undefined
(可选值)不满足约束,将接受约束,并将T推断为
(…args:any[])=>any


通过删除约束,T

这样做会使
cb
不再是可选的,并且需要作为
未定义的
提供。为什么identity不能从可选参数推断?我不太清楚为什么
identity
现在不能从
可选的
值推断,但是考虑一下
useCallback
的用例,它应该可以正常工作,因为如果没有回调函数,就不会使用
useCallback
,我错了吗?
 let result: ((foo: number) => void | undefined) = identity(...);