Удаление типовбезопасного элемента из массива в объекте - возможно ли это в одной функции без утверждения? - PullRequest
1 голос
/ 12 апреля 2019

Я спрашиваю это в основном потому, что мне любопытно.Название может быть немного сложным, так что ... Допустим, у меня есть такой объект:

type ObjType = { items: Array<{ id: number }>; sth: number };
const obj: ObjType = {
  sth: 3,
  items: [{ id: 1 }, { id: 2 }, { id: 3 }]
};

Теперь я бы хотел удалить элемент из obj.items по id, скажем, 2, и вернутьвесь объект с этим предметом удален (новый объект, не видоизмененный).Это обычно просто в JavaScript, но я бы хотел сделать это с сохранением безопасности типов в TypeScript.Я придумал что-то вроде этого:

function removeItemFromArray<S, A extends { id: number }>(
  obj: S,
  field: keyof S,
  array: A[],
  valueToCompare: number
): S {
  return {
    ...obj,
    [field]: array.filter(i => i.id !== valueToCompare)
  };
}

, но параметр array кажется избыточным - он всегда будет obj[field].Но если бы я просто использовал obj[field], нет никакой гарантии, что это массив.Теперь вопрос в том, как убедиться, что obj[field] является массивом объектов, которые содержат свойство id?Я почти уверен, что это возможно с условными типами, но я не могу понять это.

1 Ответ

1 голос
/ 12 апреля 2019

Условные типы здесь не помогут, но вы можете получить то, что хотите, убедившись, что obj имеет правильную форму:

function removeItemFromArray<S extends { [f in F]: { id: number }[] }, F extends keyof S>(
  obj: S,
  field: F,
  valueToCompare: number
): S {
  return {
    ...obj,
    [field]: obj[field].filter(i => i.id !== valueToCompare)
  };
}

const obj = {
  sth: 3,
  items: [{ id: 1 }, { id: 2 }, { id: 3 }]
};

removeItemFromArray(obj, "items", 2);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...