Typescript对每个对象应用算术运算';类型编号的s键

Typescript对每个对象应用算术运算';类型编号的s键,typescript,types,generic-programming,Typescript,Types,Generic Programming,我想知道typescript中是否有某种通用的解决方案,可以对对象的每个键应用算术运算: 例如,如果我想将一个对象的每个关键点与3相乘,我希望如下所示。 (如果该函数只对数字类型的键应用算术运算,那就更好了,但这不是必须的) 在类型系统中表达这一点是可能的,但实际上实现该函数需要一些类型转换。有可能有人比我更聪明,能够想出如何在没有这些不安全的强制转换的情况下编写函数 从类型系统的角度来看,我将其分为三个步骤: 类型属性的巧妙映射 将类型折叠为并集 拾取联合中显示的类型的子集 看起来是这样的

我想知道typescript中是否有某种通用的解决方案,可以对对象的每个键应用算术运算:

例如,如果我想将一个对象的每个关键点与3相乘,我希望如下所示。 (如果该函数只对数字类型的键应用算术运算,那就更好了,但这不是必须的)


在类型系统中表达这一点是可能的,但实际上实现该函数需要一些类型转换。有可能有人比我更聪明,能够想出如何在没有这些不安全的强制转换的情况下编写函数

从类型系统的角度来看,我将其分为三个步骤:

  • 类型属性的巧妙映射
  • 将类型折叠为并集
  • 拾取联合中显示的类型的子集
看起来是这样的(泛化为不仅仅是
number

//每个成员变为“成员”:“成员”或“成员”:从不
类型AllowedProperties={
[K in keyof TBase]:TBase[K]延伸到塔勒?K:永远不会
};
//现在将所有属性合并在一起,Never将被删除
键入允许的名称=
允许的属性[基键];
//在选定AllowedName中的成员的位置创建新类型
//从托宾
//
//请注意,“拾取”是内置的辅助对象类型
类型JustPropertiesOf=
挑选;
作为一个具体的例子,我们可以定义一个新类型,并查看这些类型对它的影响:

类型变化={
关键1:数字,
键2:字符串,
关键3:对象,
键4:数字
}
/*
类型VariedProps={
键1:“键1”;
关键2:永远不要;
关键3:永远不要;
}
*/
类型VariedProps=允许的属性;
/*
键入VariedNames=“key1”|“key4”
*/ 
键入VariedNames=允许的名称;
类型变量编号={
键1:数字;
键4:数字;
}
/*
类型variedNumber=JustPropertiesOf;
实际上,使用这些类型是很棘手的。我求助于一些
,因此您可以在函数之外进行很好的键入,但您必须确保实现。基本问题是,您不能真正创建符合
JustPropertiesOf
的对象,也不能断言要分配给它的键位于
AllowedNames

我所做的是:


函数genericOverNumbers(
普通对象:TObject,
del:(a:number)=>number):仅属性of
{
设ret:any={};
for(plainObject中的常量键){
const val=普通对象[键];
if(val类型=“编号”){
const knownKey=键;
常量映射=del(val);
ret[knownKey]=映射;
}
}
返回ret;
}

一个更通用的函数(用
TOf
代替
number
)也很棘手,因为
typeof val
保护只适用于某些受约束的类型。我可能会将类型保护函数作为参数,但这会引入一些额外的不安全性(因为您也需要将val键入
any

在类型系统中表达这一点是可能的,但实际上实现该函数需要一些
强制转换。有可能有人比我更聪明,能够想出如何在没有这些不安全的强制转换的情况下编写函数

从类型系统的角度来看,我将其分为三个步骤:

  • 类型属性的巧妙映射
  • 将类型折叠为并集
  • 拾取联合中显示的类型的子集
看起来是这样的(泛化为不仅仅是
number

//每个成员变为“成员”:“成员”或“成员”:从不
类型AllowedProperties={
[K in keyof TBase]:TBase[K]延伸到塔勒?K:永远不会
};
//现在将所有属性合并在一起,Never将被删除
键入允许的名称=
允许的属性[基键];
//在选定AllowedName中的成员的位置创建新类型
//从托宾
//
//请注意,“拾取”是内置的辅助对象类型
类型JustPropertiesOf=
挑选;
作为一个具体的例子,我们可以定义一个新类型,并查看这些类型对它的影响:

类型变化={
关键1:数字,
键2:字符串,
关键3:对象,
键4:数字
}
/*
类型VariedProps={
键1:“键1”;
关键2:永远不要;
关键3:永远不要;
}
*/
类型VariedProps=允许的属性;
/*
键入VariedNames=“key1”|“key4”
*/ 
键入VariedNames=允许的名称;
类型变量编号={
键1:数字;
键4:数字;
}
/*
类型variedNumber=JustPropertiesOf;
实际上,使用这些类型是很棘手的。我求助于一些
,因此您可以在函数之外进行很好的键入,但您必须确保实现。基本问题是,您不能真正创建符合
JustPropertiesOf
的对象,也不能断言要分配给它的键位于
AllowedNames

我所做的是:


函数genericOverNumbers(
普通对象:TObject,
del:(a:number)=>number):仅属性of
{
设ret:any={};
for(plainObject中的常量键){
const val=普通对象[键];
if(val类型=“编号”){
const knownKey=键;
常量映射=del(val);
ret[knownKey]=映射;
}
}
返回ret;
}
一个更通用的函数(用
TOf
代替
number
)也很棘手,因为
typeof val
保护只适用于某些受约束的类型。我可能会将类型保护函数作为参数,但这会引入一些额外的不安全性(因为您也需要将val键入
any

type type1 = {
  key1: number;
};

type type2 = {
  key2: number;
  key3: number;
};

let obj1: type1 = {
  key1: 1,
};

let obj2: type2 = {
  key2: 2,
  key3: 3,
};

genericFunc(obj1);
genericFunc(obj2);

// Expected result:
// obj1 = {
//   key1: 3,
// };

// obj2 = {
//   key2: 6,
//   key3: 9,
// };