当对函数参数使用推理时,如果不适用于实用程序类型参数,Typescript 会引发错误。举个例子:[操场 https://www.typescriptlang.org/play?#code/JYOwLgpgTgZghgYwgAgGLADaSgHgCoB8yA3gFDIXIAUoADgFzJ4CUjARgPYcYRwgDcpAL6lSYAJ60UASRC0ACnChwAtjlTIIAD0ggAJgGc0mbDhAQAbtAJEAvMkXKVEbAfUEA2gAYAuoIlSyLK0sjDQ6po6EPpG6Fjh5lZQNsj2Gtq6hsbxuKBhUExEAPxMyIyJ0IKkMACuIAhgwBwgyADuygpKqhEZ0VlxphXJBFQwJoyorNmmwY7dqClklMgIzQZgbR1SBfY0coyzXWoLU5zcvC22RGNYe7TMgstQLjVQLe1wtNuCItV1DU13h1QuF0lEYtMEpZrCMbmAJlMBuFgiDcAsiEtKKsQOtNp9tqlqHQDnJUe5TlweHxUtcTHcHuRKM8wK8gfjKsJRAEUABlYAqWg8AaEqjMGnIM5UgRiSQoOYqQmHJw4PkCoUmAj8CgAem1yDqeggY3MehlgVRitJIHyKv5gogA01yF1+pAAGsQBxWiBSEA]
interface Filter<T> {
(inp: T): boolean;
}
// get parameter using Parameters
type InpParam<F extends Filter<never>> = Parameters<F>[0];
// get parameter using infer
type InpInfer<F extends Filter<never>> = F extends Filter<infer T> ? T : never;
// compiles fine
function wrapParam<F extends Filter<never>>(filt: F): Filter<InpParam<F>> {
const wrapper = (inp: InpParam<F>): boolean => filt(inp);
return wrapper;
}
function wrapInfer<F extends Filter<never>>(filt: F): Filter<InpInfer<F>> {
const wrapper = (inp: InpInfer<F>): boolean => filt(inp);
// ^^^
// argument of type InpInfer<F> is not assignable to type never
return wrapper;
}
我不太确定为什么 InpParam 可以分配给 never,例如当 InpInfer 不是并且被推断为未知时,被推断为从不。我可能与他们如何处理空参数有关,但这里参数实际上返回了错误的东西,它返回未定义而不是未知。 (错误的是,我的意思是未知是更通用的输入参数,因为函数参数是逆变的)。
我很好奇如何解决这个问题,原因有两个:
-
undefined
类型太窄,实际类型应该是unknown
。当与另一种类型相交时,这会带来一个特殊的问题,因为unknown & T
=> T
but undefined & {}
=> never
.
- 对于复杂的输入类型,编写表达式来提取嵌套类型可能很复杂、难以阅读,并且对于更改对象定义来说很脆弱。然而,只要泛型具有相同的语义,Infer 就始终有效。
Notes
- 我知道可以通过在输入参数中使包装器通用来编写有问题的特定包装器,但是如果我还想保留过滤器本身的类型,则情况并非如此(为了清楚起见,这些示例并未说明这一点) 。
- 我还知道这里的特定包装器不执行任何操作,因此可以省略。
None
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)