【发布时间】:2022-01-07 09:40:57
【问题描述】:
我实现了一个函数(我们称之为valuesOfThings),它接受一个具有任意键名和特定对象类型Thing(实际上是Map)的值的对象。然后该函数应该返回一个具有相同键的对象,但每个键的值应该是 Thing 的某个键的值。
例如我想转换这个:
const things = {
someThing: { value: 10 },
otherThing: { value: 'foo'},
}
到这里:
const values = {
someThing: 10,
otherThing: 'foo',
}
并且我希望正确输入返回的对象。
函数的JS实现如下:
function valuesOfThings(things) {
const values = Object.fromEntries(
Object.entries(things)
.map(([key, thing]) => [key, thing.value])
// ^^^^^^^^^^^----- the important part
)
return values
}
基于this question,我设法制作了以下返回类型:
{[key in keyof T]: T[key] extends Thing<infer ValueType> ? ValueType : never}
让我们看看它的实际效果:
type Thing<T> = {
value: T
}
type ThingMap = {
[key: string]: Thing<unknown>
}
function valuesOfThings_1<T extends ThingMap>(things: T): {[key in keyof T]: T[key] extends Thing<infer ValueType> ? ValueType : never} {
const values = Object.fromEntries(
Object.entries(things)
.map(([key, thing]) => [key, thing.value])
)
return values as {[key in keyof T]: T[key] extends Thing<infer ValueType> ? ValueType : never}
}
如您所见,返回类型比较长,returning 时必须重复。但至少它会产生正确的类型,当我悬停返回的变量时,我会看到我期望的类型:
当我尝试像这样提取这种类型时:
type ThingValuesMap<T> = {
[key in keyof T]: T[key] extends Thing<infer ValueType> ? ValueType : never
}
function valuesOfThings<T extends ThingMap>(things: T): ThingValuesMap<T> {
return Object.fromEntries(
Object.entries(things)
.map(([key, thing]) => [key, thing.value])
) as ThingValuesMap<T>
}
结果类型没有正确解析:
但是,智能感知知道正确的类型:
如您所见,otherThing 的类型正确显示为string。
我创建了一个 TS 游乐场here。将鼠标悬停在 values_1 和 values_2 以查看区别。
为什么提取返回类型时类型显示不正确?我在这里做错了吗?
【问题讨论】: