如何在TypeScript中对任意对象的属性进行常规迭代?

如何在TypeScript中对任意对象的属性进行常规迭代?,typescript,types,typescript-generics,parametric-polymorphism,type-variables,Typescript,Types,Typescript Generics,Parametric Polymorphism,Type Variables,这是一种非常常见的JavaScript模式: function mapThruWrapper(module) { const replacement = {} Object.getOwnPropertyNames(module).forEach(function(key) { const val = module[key] if (val instanceof Function) { replacement[key] = wrapperF

这是一种非常常见的JavaScript模式:

function mapThruWrapper(module) {
   const replacement = {}

   Object.getOwnPropertyNames(module).forEach(function(key) {
      const val = module[key]

      if (val instanceof Function) {
         replacement[key] = wrapperFunc.bind(null, val)
      } else {
         replacement[key] = val
      }
   })

   return replacement
}
我试图在TypeScript中强烈地键入它,我已经得到了如下结果:

function mapThruWrapper<M extends { [X: string]: unknown }>(module: M): M {
   const replacement: M = {}

   Object.getOwnPropertyNames(module).forEach(function(key) {
      const val = module[key]

      if (val instanceof Function) {
         replacement[key] = wrapperFunc.bind(null, val)
      } else {
         replacement[key] = val
      }
   })

   return replacement
}

如何在这样一个对象的成员上强式键入泛型迭代并进行包装?

我对原始代码进行了一些调整,并添加了注释来解释:

function mapThruWrapper<M extends { [X: string]: unknown }>(module: M): M {
    // Add "as M" so that the compiler allows us to assign an
    // empty object (which is okay since we're populating all the
    // object's properties before the function returns anyway).
    const replacement: M = {} as M

    // Use "for in" so that the compiler is able to infer
    // that the variable "key" isn't just a string, but is
    // actually a key in module's type.
    for (const key in module) {
        if (module.hasOwnProperty(key)) {
            const val = module[key]

            if (val instanceof Function) {
                // Use "as typeof val" to let the compiler know that the
                // bound function has the same signature as the original
                // function. I'm assuming that's the case here.
                replacement[key] = wrapperFunc.bind(null, val) as typeof val
            } else {
                replacement[key] = module[key]
            }
        }
    }

    return replacement
}
函数mapThruWrapper(模块:M):M{
//添加“as M”,以便编译器允许我们分配
//空对象(这是可以的,因为我们正在填充所有
//函数返回之前的对象属性)。
常量替换:M={}为M
//使用“for in”以便编译器能够推断
//变量“key”不仅仅是一个字符串,而是
//实际上是模块类型中的一个键。
for(常数输入模块){
if(模块hasOwnProperty(键)){
const val=模块[键]
if(val instanceof函数){
//使用“as typeof val”让编译器知道
//绑定函数与原始函数具有相同的签名
//函数,我假设这里是这样的。
replacement[key]=wrapperFunc.bind(null,val)作为val的类型
}否则{
替换[键]=模块[键]
}
}
}
退换货
}
function mapThruWrapper<M extends { [X: string]: unknown }>(module: M): M {
    // Add "as M" so that the compiler allows us to assign an
    // empty object (which is okay since we're populating all the
    // object's properties before the function returns anyway).
    const replacement: M = {} as M

    // Use "for in" so that the compiler is able to infer
    // that the variable "key" isn't just a string, but is
    // actually a key in module's type.
    for (const key in module) {
        if (module.hasOwnProperty(key)) {
            const val = module[key]

            if (val instanceof Function) {
                // Use "as typeof val" to let the compiler know that the
                // bound function has the same signature as the original
                // function. I'm assuming that's the case here.
                replacement[key] = wrapperFunc.bind(null, val) as typeof val
            } else {
                replacement[key] = module[key]
            }
        }
    }

    return replacement
}