使用可选 id 操作 Flow 通用类型的列表

Manipulate list of Flow generic type with optional id

我想要一个函数,它接受一个数组,其中的对象可以有 id 属性。该函数将删除具有 id 且与函数的第二个参数匹配的第一个对象。

这是我的存根:

// @flow

function removeFromArrayByObjectId<T: {id?: string}>(array: Array<T>, id: any): Array<T> {
  for (let i = 0; i < array.length; i++) {
    if (array[i].id && array[i].id === id) { 
      array.splice(i, 1);
      break;
    }
  }
  return array;
}

export {
  removeFromArrayByObjectId,
};

当我通过 arr 定义为(下)时,我得到

type Obj = { id: string, value: string };
const arr: Array<Obj> = [obj1, obj2];

Cannot call removeFromArrayByObjectId with array literal bound to array because string [1] is incompatible with undefined [2] in property id of array element.Flow(InferError)

但是,当我从 id? 中删除 ? 时,它工作正常。我期望某些数组将包含没有 id 的元素,因此希望它是可选的。有什么建议吗?

该错误与 中提到的错误非常相似。本质上,Flow 并不知道 removeFromArrayByObjectId 不操作 array 的元素(例如,删除一个 属性)。您需要将 T 标记为 "read-only",以便 Flow 知道函数不会这样做。

function removeFromArrayByObjectId<T: $ReadOnly<{id?: string}>>(array: Array<T>, id: any): Array<T> {
  for (let i = 0; i < array.length; i++) {
    if (array[i].id && array[i].id === id) { 
      array.splice(i, 1);
      break;
    }
  }
  return array;
}

type Obj = { id: string, value: string };
declare var obj1: Obj;
declare var obj2: Obj;
const arr: Array<Obj> = [obj1, obj2];
const modified_arr: Array<Obj> = removeFromArrayByObjectId(arr);

Try Flow