【发布时间】:2020-12-15 09:47:17
【问题描述】:
以这个函数为例
type Decoder<A, B> = (v: A) => B
declare function test<Values, D extends Decoder<Values, unknown>>(options: {
values: Values,
decoder: D,
onDecoded: (decodedValue: ReturnType<D>) => unknown
}): void;
这个想法是onDecoded 输入由decoder 计算的值。然而:
test({
values: { a: "" },
decoder: values => values.a.length,
onDecoded: decodedValue => {
decodedValue // unknown
}
})
奇怪的是,如果我在decoder 的定义中不使用values,那么decodedValue 的类型是正确的
test({
values: { a: "" },
decoder: () => 42,
onDecoded: decodedValue => {
decodedValue // number
}
})
这是一个playground link 与相同的例子
有没有办法让原始示例工作?
【问题讨论】:
-
更奇怪的是(对我来说),
decodedValue的类型会更改为number,如果你只是将decoder更改为decoder: (values) => 42。只是声明参数,甚至不使用它,改变了事情。 -
嘿,谢谢你的问题。确实
D扩展了Decoder<Values, unknown>,但它的实际类型被推断为Decoder<Values, number>,所以我预计ReturnType<D>会导致number。这不是一个公平的假设吗? -
是的,我对
unknown类型还很陌生,但我想我明白了。谢谢。 -
你可以替换那里的任何东西,真的。
unknown只是这个案例的合理上限,但理想情况下我希望它永远不会被推断出来 -
是的,我也注意到了这种行为。似乎只是添加参数会改变类型推断算法......
标签: typescript type-inference typescript-generics