【问题标题】:How do I make this typescript mapping function much less complex?如何使这个打字稿映射功能变得不那么复杂?
【发布时间】:2018-10-17 00:24:49
【问题描述】:

我正在尝试在一些已知值与其他一些已知值之间做一个非常简单的映射。这段代码的一切都在尖叫我错过了打字稿可以做的一些简单的事情。

type PortInfoProp = 'comName' | 'manufacturer' | 'serialNumber' | 'vendorId' | 'productId' | 'pnpId'

interface LinuxPort extends PortInfo {}

interface PropNames {
  readonly DEVLINKS: PortInfoProp
  readonly DEVNAME: PortInfoProp
  readonly ID_MODEL_ID: PortInfoProp
  readonly ID_SERIAL_SHORT: PortInfoProp
  readonly ID_VENDOR_ENC: PortInfoProp
  readonly ID_VENDOR_ID: PortInfoProp
}

type PropName = keyof PropNames

function propName(name: PropName): PortInfoProp | null {
  const map: PropNames = {
    DEVNAME: 'comName',
    ID_VENDOR_ENC: 'manufacturer',
    ID_SERIAL_SHORT: 'serialNumber',
    ID_VENDOR_ID: 'vendorId',
    ID_MODEL_ID: 'productId',
    DEVLINKS: 'pnpId',
  }
  return map[name] || null
}

【问题讨论】:

    标签: javascript typescript types node-serialport


    【解决方案1】:

    我要做的第一件事就是将你的地图移到函数之外;无需在每次通话时重新创建它。然后,您可以将映射声明为字典:

    type PropName = 'DEVNAME' | 'ID_VENDOR_ENC' | 'ID_SERIAL_SHORT' | 'ID_VENDOR_ID' | 'ID_MODEL_ID' | 'DEVLINKS';
    type PortInfoProp = 'comName' | 'manufacturer' | 'serialNumber' | 'vendorId' | 'productId' | 'pnpId';
    
    type PropertyMapping = { [key in PropName]: PortInfoProp };
    
    const map: PropertyMapping = {
      DEVNAME: 'comName',
      ID_VENDOR_ENC: 'manufacturer',
      ID_SERIAL_SHORT: 'serialNumber',
      ID_VENDOR_ID: 'vendorId',
      ID_MODEL_ID: 'productId',
      DEVLINKS: 'pnpId',
    }
    
    function propName(name: PropName): PortInfoProp | null {
      return map[name] || null
    }
    

    编辑

    如果您不想为地图键/值命名类型,则更简洁:

    const map = {
      DEVNAME: 'comName',
      ID_VENDOR_ENC: 'manufacturer',
      ID_SERIAL_SHORT: 'serialNumber',
      ID_VENDOR_ID: 'vendorId',
      ID_MODEL_ID: 'productId',
      DEVLINKS: 'pnpId',
    }
    
    type PropMapping = typeof map;
    
    function propName<K extends keyof PropMapping>(name: K): PropMapping[K] | null {
      return map[name] || null
    }
    

    【讨论】:

    • 当然,给定map 在第二个变体中,可以定义命名类型type PropName = keyof PropMappingtype PortInfoProp = PropMapping[PropName]
    • 同样在第二个变体中,如果您执行const lit = &lt;K extends string | number | boolean&gt;(k: K) =&gt; k; 然后{ DEVNAME: lit('comName'), ID_VENDOR_ENC: lit('manufacturer') ... } 之类的操作,您可以恢复您的字符串文字类型。
    【解决方案2】:

    switch 语句更简洁一些。

    type PortInfoProp = 'comName' | 'manufacturer' | 'serialNumber' | 'vendorId' | 'productId' | 'pnpId'
    type PropName = 'DEVLINKS' | 'DEVNAME' | 'ID_MODEL_ID' | 'ID_SERIAL_SHORT' | 'ID_VENDOR_ENC' | 'ID_VENDOR_ID'
    
    function propName(name: PropName): PortInfoProp | null {
      switch (name) {
        case 'DEVNAME':
          return 'comName'
        case 'ID_VENDOR_ENC':
          return 'manufacturer'
        case 'ID_SERIAL_SHORT':
          return 'serialNumber'
        case 'ID_VENDOR_ID':
          return 'vendorId'
        case 'ID_MODEL_ID':
          return 'productId'
        case 'DEVLINKS':
          return 'pnpId'
        default:
          return null
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2021-06-30
      • 2021-08-13
      • 2014-05-19
      • 2019-11-19
      • 2022-10-13
      • 2022-08-17
      • 2017-02-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多