【问题标题】:Typing for an array of certain values, where each value may appear at most once? (TypeScript)键入某些值的数组,其中每个值最多出现一次? (打字稿)
【发布时间】:2020-11-07 00:35:28
【问题描述】:

假设我有如下函数:

function getUserInfo(desiredProperties: ('name' | 'age' | 'salary')[]) {
  const userInfo: Record<string, unknown> = {};
  for (const propertyName of desiredProperties) {
    userInfo[propertyName] = fetchEffortfullyFromDatabase(...);
  }
  return userInfo;
}

现在,如果我“正常”调用该函数,请说

const userInfo = getUserInfo(['name', 'salary']);

一切都很好。 但没有什么能阻止一个人像这样的电话

const userInfo = getUserInfo(['name', 'name', 'name', ...]);

触发许多不必要的数据库访问。当然,这可以简单地在运行时在getUserInfo 中处理,但我希望编译器能够识别并禁止此类调用。

我可以将('name' | 'age' | 'salary')[] 更改为propertyNames 的所有可能组合的并集,即['name'] | ['name', 'age'] | ['name', 'age', 'salary'] | ['age'] | ...,但即使对于三个值,这也太乏味了,而且很难实现更多(尤其是考虑到顺序时)。

那么,是否有另一种方法来获得所需的输入?也许像AllCombinations&lt;'name', 'age', 'salary'&gt; 这样的东西?

【问题讨论】:

    标签: arrays typescript subset


    【解决方案1】:

    您可以使用Set 类型功能仅提取传递参数的唯一成员:

    function getUserInfo(desiredProperties: ('name' | 'age' | 'salary')[]) {
      const uniqueMembers = new Set(desiredProperties); // this extract only unique members of array
      const userInfo: Record<string, unknown> = {};
      for (const propertyName of uniqueMembers) { // and here you iterate only through unique members
        userInfo[propertyName] = fetchEffortfullyFromDatabase(...);
      }
      return userInfo;
    }
    
    let userInfo = getUserInfo(['name', 'salary']);
    
    userInfo = getUserInfo(['name', 'name', 'name']);
    

    当然,这样的解决方案并不完美,因为它假定了运行时不必要的计算。

    如果不想进行不必要的计算,可以将desiredProperties的类型设置为Set&lt;'name' | 'age' | 'salary'&gt;。然后像这样调用getUserInfo

    const userInfo = getUserInfo(new Set(['name', 'salary']));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-06-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-05
      • 1970-01-01
      • 2019-10-27
      相关资源
      最近更新 更多