Задать вопрос
Fragster
@Fragster
помогло? отметь решением!

Как заставить typescript поверить, что в объекте есть свойство?

Перевожу прооект на typescript, параллельно разбираясь с этим самым typescript'ом
Есть вот такой кусок кода:
export async function create (path: string, data: object) {
  return (await api.post(`${path}`, data)).data.data
}

export async function update (path: string, data: { id: number | string }) {
  return (await api.put(`${path}/${data.id}`, data)).data.data
}

export async function upsert (path: string, data: { id?: number | string }) {
  if (Object.hasOwn(data, 'id')) { // тут пробовал разные проверки наличия свойства у объекта
    return await update(path, { ...data, id: data.id ?? '' }) // но никакая проверка не помогает, пришлось подставить костыль
  } else {
    return await create(path, data)
  }
}


как заставить поверить typescript что свойство есть, чтобы убрать костыль и передавать просто data?
  • Вопрос задан
  • 116 просмотров
Подписаться 1 Простой 7 комментариев
Решения вопроса 2
modelair
@modelair
unsocial
есть такая штука - typeguard. он сообщает ts'у, что этот объект определенного типа, который указан после is. вот простенький, дальше разберешься, думаю.

function isData(data: any): data is { id: number | string } {
  return data.id !== undefined
}
Ответ написан
WblCHA
@WblCHA
Тебе надо юнион здесь и тогда тс поймёт, что дата может быть только одного типа после проверки.
export async function upsert(
  path: string,
  data: { id?: never } | { id: number | string }
) {
  if (data.id !== undefined) {
    return update(path, data)
  } else {
    return create(path, data)
  }
}

Но даже это не до конца верно, потому что у тебя передаваемый объект полностью должен быть типизирован и тогда получаем что-то в этом роде:
interface SomeDataCreate {
  name: string
}

interface SomeDataUpdate {
  id: number | string
  name: string
}

export async function upsert(
  path: string,
  data: SomeDataCreate | SomeDataUpdate
) {
  if ("id" in data) {
    return update(path, data)
  } else {
    return create(path, data)
  }
}
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы