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(...);