繁体   English   中英

如何在打字稿中为对象的通用键类型分配值类型?

[英]How assign a value type to a generic key type of an object in typescript?

我正在尝试编写一个合并的函数,并将已经排序的数组排序为一个排序数组。 它接受对象数组的数组,以及将作为比较基础的比较键。 我需要确保提供的键的值始终是一个数字。

这是我到目前为止的情况:

const sortMerge = <
  A extends Array<I>,
  K extends keyof A[number],
  I = A[number] & {
    [key in K]: number;
  },
>(
  arrays: A[],
  key: K,
  sortMethod = SortMethod.asc,
) => {
  const indexesOfArrays = arrays.map(() => 0);

  const mergedSorted = [];

  while (arrays.some((array, i) => array.length > indexesOfArrays[i])) {
    const currentItemsOfArrays = arrays.map(
      (array, arrayIndex) => array[indexesOfArrays[arrayIndex]],
    );
    const comparison = currentItemsOfArrays.map((item) =>
      item ? item[key] : (sortMethod === SortMethod.asc ? Infinity : -Infinity),
    );

    const nextArrayIndex = comparison.indexOf(
      Math[sortMethod === SortMethod.asc ? 'min' : 'max'](...comparison),
    );
    const nextItem = currentItemsOfArrays[nextArrayIndex];

    mergedSorted.push(nextItem);
    indexesOfArrays[nextArrayIndex]++;
  }
  return mergedSorted;
};

一切都很好,但它不会将I[K]识别为number ,但这就是我试图将KI定义为泛型。

我究竟做错了什么?

预期的错误/类型:

 const missingKey = [ { a: 1 } ]; const valid = [ { a: 2, b: 3 } ]; const anotherValid = [ { c: 3, b: 4 } ]; sortMerge([missingKey, valid], 'b') // missingKey[number] is missing property 'b'; sortMerge([valid, anotherValid], 'b') // expected return type: ({ a: number, b: number } | { c: number, b: number })[]

我稍微改变了通用约束:

enum SortMethod {
  asc = 'asc',
}
const sortMerge = <
  Key extends PropertyKey,
  Elem1 extends Record<Key, number>,
  Elem2 extends Record<Key, number>,

  Arr1 extends Elem1[],
  Arr2 extends Elem2[],
  Arrays extends [Arr1, Arr2]
>(
  arrays: [...Arrays],
  key: Key,
  sortMethod = SortMethod.asc,
): (Arrays[number][number])[] => {
  const indexesOfArrays = arrays.map(() => 0);

  const mergedSorted = [];

  while (arrays.some((array, i) => array.length > indexesOfArrays[i])) {
    const currentItemsOfArrays = arrays.map(
      (array, arrayIndex) => array[indexesOfArrays[arrayIndex]],
    );
    const comparison = currentItemsOfArrays.map((item) =>
      item ? item[key] : (sortMethod === SortMethod.asc ? Infinity : -Infinity),
    );

    const nextArrayIndex = comparison.indexOf(
      Math[sortMethod === SortMethod.asc ? 'min' : 'max'](...comparison),
    );
    const nextItem = currentItemsOfArrays[nextArrayIndex];

    mergedSorted.push(nextItem);
    indexesOfArrays[nextArrayIndex]++;
  }
  return mergedSorted;
}

const missingKey = [{ a: 1 }];
const valid = [{ a: 2, b: 3 }];
const anotherValid = [{ c: 3, b: 4 }];

sortMerge([missingKey, valid], 'b') // missingKey[number] is missing property 'b';
const x = sortMerge([valid, anotherValid], 'b')

操场

如果要推断数组中嵌套对象或对象的键,则应从底部开始。

Key - 对象的推断属性

Elem - 推断的对象,其中键是Key

Arr - 推断的Elem数组

Arrays - 推断的Arr数组

正如您可能已经注意到的那样,我从推断 prop 的底层开始,并完成了对顶层参数的推断。

如果您对函数参数的类型推断感兴趣,可以查看我的文章

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM