【问题标题】:Returning object with key value pairs based on arguments in Typescript基于Typescript中的参数返回具有键值对的对象
【发布时间】:2020-05-14 17:13:57
【问题描述】:

我想创建一个循环遍历对象中的键/值对并返回具有相同键的对象的函数,但现在每个值都变成了一个函数。我想确保打字稿正确掌握返回的对象以进行自动完成。这适用于以下愚蠢的功能:

interface Args {
  [layer: string]: Boolean
}

function sillyFunction<T extends Args>(layers: T): T {
  return layers
}

sillyFunction({ layerName: true }).layerName // this works

但现在我有以下代码,其中层对象(键/布尔对)用于创建具有键/函数对的新 returnObject。:

interface Args {
  [layer: string]: Boolean
}

interface ReturnedObject {
  [layer: string]: Function
}

function createFunctions<T extends Args>(layers: T): T {
  let returnObj = {} as ReturnedObject;

  for (let layer in layers) {
    returnObj[layer] = (label) => `${layer} ${label}`
  }

  return returnObj;
}

createFunctions({ layerName: true }).layerName // doesnt work

这显然给了我错误'ReturnedObject' is not assignable to type T。我如何确保打字稿'理解'对象内的键仍然相同,但值已成为函数?

【问题讨论】:

    标签: typescript


    【解决方案1】:

    您的“createFunctions”返回类型是 T,但您希望是 ReturnedObject。

    只需将返回类型定义为 ReturnedObject

    function createFunctions<T extends Args>(layers: T): ReturnedObject
    

    它应该可以工作

    【讨论】:

    • 是的,但是你会失去类型安全性。 OP 希望 ReturnedObject 的键与 T 相同。
    • 这将消除错误,但实际上不会保留T 的键,返回类型将允许访问任何键,因为它具有索引签名
    【解决方案2】:

    您需要使用映射类型将T 转换为具有相同属性但每个属性的类型不同的新类型。预定义的类型Record 在这种情况下会很好地工作,因为所有的键都将具有相同的类型。另外我会比Function更具体的函数类型,Function是函数签名的any,它允许使用任何参数调用

    interface Args {
      [layer: string]: boolean
    }
    
    type ReturnedObject<T> =  Record<keyof T, (label: string) => string>
    
    function createFunctions<T extends Args>(layers: T): ReturnedObject<T> {
      let returnObj = {} as ReturnedObject<T>;
    
      for (let layer in layers) {
        returnObj[layer] = (label) => `${layer} ${label}`
      }
    
      return returnObj;
    }
    
    var l = createFunctions({ layerName: true })
    l.layerName("") 
    

    Playground Link

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-01
      • 1970-01-01
      • 2019-09-28
      • 2021-10-02
      • 2017-11-16
      • 1970-01-01
      相关资源
      最近更新 更多