Typescript &引用;剖析;具有泛型类型的对象(使用lodash/mapValues)
我希望实现一个通用函数,它接受一个类型化对象并返回该对象的一个变体(“被某个键解析”) 我的MWE遵循一个带有断点的示例,在该示例中,我有一个函数,可以从我的configTypescript &引用;剖析;具有泛型类型的对象(使用lodash/mapValues),typescript,typescript-generics,Typescript,Typescript Generics,我希望实现一个通用函数,它接受一个类型化对象并返回该对象的一个变体(“被某个键解析”) 我的MWE遵循一个带有断点的示例,在该示例中,我有一个函数,可以从我的configresponsiveObj返回适当的屏幕大小属性。为简洁起见,该函数被锁定为sm,但我的键入问题应被捕获: const responsiveObj = { firstItem, secondItem }; // Where // (property) firstItem: Partial<Record<Breakpo
responsiveObj
返回适当的屏幕大小属性。为简洁起见,该函数被锁定为sm
,但我的键入问题应被捕获:
const responsiveObj = { firstItem, secondItem };
// Where
// (property) firstItem: Partial<Record<Breakpoints, PrimaryProps>>
// (property) secondItem: Partial<Record<Breakpoints, PrimaryProps & SecondaryProps>>
...
const responsiveFn = <T extends any, K extends keyof T>(
responsive: Record<K, ResponsiveProps<UnknownGeneric>>
) => {
// Dummy sm output
const out = _.mapValues(responsive, (o) => {
return { ...o.sm };
});
return out;
};
const result = responsiveFn(responsiveObj);
// Height is part of PrimaryProps and is identified
result.firstItem.height;
// Visible is part of SecondaryProps and is _not_ identified
result.secondItem.visible;
const responsiveObj={firstItem,secondItem};
//在哪里
//(属性)第一项:部分
//(财产)第二项:部分
...
常数响应fn=(
回应:记录
) => {
//虚拟sm输出
常量输出=\映射值(响应,(o)=>{
返回{…o.sm};
});
返回;
};
常数结果=响应fn(响应obj);
//高度是PrimaryProps的一部分,已确定
结果:第一项:身高;
//Visible是次要道具的一部分,未被识别
result.secondItem.visible;
我希望SecondaryProps
不要在函数中迷失方向
请参阅完整示例。在类型级别,您所称的“分离”似乎如下所示:
- 从am对象类型
开始,使用任意属性键,这些属性键的属性值是T
的某些子类型ResponsiveProps
- 对于
中的每个属性键T
,输出对象类型在键K
处也将有一个属性。所以我们想使用一个形式为K
{[K in keyof T]:…}
- 对于每个属性值类型
,即T[K]
的某个子类型,输出属性值类型将是ResponsiveProps
断点处的属性值之一。也就是说,
T[K][Breakpoints]
- 请注意,这很可能是
(因为未定义的
具有所有可选属性),但即使输入不存在,您的输出似乎也会生成一个对象(您正在编写ReponsiveProps
,如果{…(o.sm)}
是o.sm
,那么它将是未定义的
)。因此,我们希望指定use以从输出类型属性中删除{}
未定义的可能性:
responsiveFn
一个这样的类型签名:
/* const responsiveFn: <T extends Record<keyof T, ResponsiveProps>(
responsive: T) => { [K in keyof T]: NonNullable<T[K][Breakpoints]>; } */
请注意,编译器无法验证输出值是否符合带注释的映射类型,因此我使用作为任何
来抑制编译器警告
如果我使用该版本,您将得到:
const result = responsiveFn(responsiveObj);
/* const result: {
firstItem: PrimaryProps;
secondItem: (PrimaryProps & SecondaryProps);
} */
console.log(result.firstItem.height) // 100
console.log(result.secondItem.visible) // false
看起来不错
这是您要找的吗?如果是这样的话,我很乐意写一个解释它的答案。如果没有,请详细说明问题;理想情况下,您不会依赖于任何第三方库(如lodash),除非该问题与这些库特别相关或与它们一起标记。。。因此,我将
.mapValues
替换为对象.fromEntries()
,对象.entries()
,以及数组映射()
。让我知道。是的,@jcalz你的回答解决了我的问题。如果您能详细说明,我将不胜感激,我很难理解它是如何工作的。
const result = responsiveFn(responsiveObj);
/* const result: {
firstItem: PrimaryProps;
secondItem: (PrimaryProps & SecondaryProps);
} */
console.log(result.firstItem.height) // 100
console.log(result.secondItem.visible) // false