【问题标题】:How to type a function that returns the single element in an array that lives in a property from an object如何键入一个函数,该函数返回位于对象属性中的数组中的单个元素
【发布时间】:2020-09-04 09:04:27
【问题描述】:

我有这个功能

function single<T, TElem, K extends keyof T>(obj: T, name: K): TElem {
  const source = obj[name];
  if (source.length !== 1) {
    throw Error(`Debería existir exactamente un ${name} asociado`);
  }
  return _.first(source);
}

该函数的思想是返回一个数组中的唯一值,该数组位于原始对象的指定属性中。问题是我不知道如何用这样的方式键入该函数:

function single<T, TElem, K extends keyof T>(obj: T, name: K): TElem 
   where T[K] extends TElem[]
{
  const source = obj[name];
  if (source.length !== 1) {
    throw Error(`Debería existir exactamente un ${name} asociado`);
  }
  return _.first(source);
}

有没有办法做到这一点?

【问题讨论】:

    标签: typescript typescript-generics


    【解决方案1】:

    我倾向于使用这样的打字方式:

    function single<K extends PropertyKey, T extends Record<K, any[]>>(
      obj: T, 
      name: K
    ): T[K][number] {
        const source = obj[name];
        if (source.length !== 1) {
            throw Error(`Debería existir exactamente un ${name} asociado`);
        }
        return source[0];
    }
    

    所以name 类似于K,而obj 必须是在其name-valued 属性处具有数组的T 类型。然后输出类型为T[K][number];当您使用 K 类型的属性对 T 进行索引,然后使用 number 类型的属性对其进行索引时,这就是您得到的类型......这意味着它是 obj[name][0] 的类型。

    让我们看看它是否有效:

    const obj = {
        a: [1],
        b: "not me",
        c: ["okay"],
    };
    
    const num = single(obj, "a");
    num.toFixed();
    
    const oops = single(obj, "b"); // error!
    // ---------------> ~~~
    // string is not compatible with any[]
    
    const str = single(obj, "c"); // okay
    str.toUpperCase();
    
    const alsoOops = single(obj, "d"); // error!
    // -------------------> ~~~
    // prop "d" is missing in obj
    

    我觉得不错。好的,希望有帮助;祝你好运!

    Playground link to code

    【讨论】:

      猜你喜欢
      • 2019-10-25
      • 2021-07-17
      • 1970-01-01
      • 2013-08-23
      • 1970-01-01
      • 2021-06-10
      • 2019-03-03
      • 2016-04-12
      • 1970-01-01
      相关资源
      最近更新 更多