Задать вопрос
@awenn2015
Веб-программист самоучка

Почему typescript не видит перегрузку?

есть вот такой незамысловатый тип:

export type NavDataItem =
  | {
      name: string;
      link: string;
    }
  | {
      name: string;
      children: NavDataItem[];
    };


На основе него я делаю соответствующий массив объектов:

export const navData: NavDataItem[] = [
  {
    name: "Название меню 1",
    link: "path_to_page",
  },
  {
    name: "Название меню 2",
    children: [
    {
      name: "Название меню 1",
      link: "path_to_page",
    },
{
      name: "Название меню 2",
      link: "path_to_page",
    },
  ]
  },
]


Но при использовании typescript почему то в автокомплите показывает свойство name игнорируя остальные

Изменено:

Попробовал поменять тип на такой но по прежнему не работает

interface NavDataBase {
  name: string;
  link: string;
}

interface NavDataChilds {
  name: string;
  children: NavDataBase[];
}

export type NavDataList = (NavDataBase | NavDataChilds)[];
  • Вопрос задан
  • 88 просмотров
Подписаться 1 Простой Комментировать
Решения вопроса 4
@HealSpirit
Можно сделать защитников типа:
interface INavDataBase {
  name: string;
  link: string;
}

interface INavDataChilds {
  name: string;
  children: INavDataBase[];
}

type TNavData = INavDataBase | INavDataChilds;

export const navData: TNavData[] = [
  {
    name: "Название меню 1",
    link: "path_to_page",
  },
  {
    name: "Название меню 2",
    children: [
      {
        name: "Название меню 1",
        link: "path_to_page",
      },
      {
        name: "Название меню 2",
        link: "path_to_page",
      },
    ],
  },
];

// Здесь можно по разному проверять и hasOwnProperty или "link" in navData
export const isNavDataBase = (navData: TNavData): navData is INavDataBase =>
  navData.hasOwnProperty("link");

export const isNavDataChilds = (navData: TNavData): navData is INavDataChilds =>
  navData.hasOwnProperty("children");

navData.forEach((data) => {
  if (isNavDataBase(data)) {
    // Здесь будет автокомплит при обращении - data.link
  } else {
    // И здесь, хотя второго защитника мы не использовали - data.children
  }
});
Ответ написан
Комментировать
Alexandroppolus
@Alexandroppolus
кодир
typescript почему то в автокомплите показывает свойство name игнорируя остальные

Оно и понятно: ts может быть уверен только в наличии name, потому как неизвестно, какой там вариант из двух.

Попробуй так:
if ("children" in obj) {
    obj.children ...
} else {
    obj.link ....
}


По идее ts должен определять, что к чему
Ответ написан
Комментировать
Aetae
@Aetae Куратор тега TypeScript
Тлен
На самом деле вопрос в IDE. Вот тут нормально всё подсказывает например.

Другой вопрос, что при заданном так типе ты можешь писать и link и children одновременно. Чтоб такого делать typescript не давал нужно поле-дискриминатор, типа:
export type NavDataItem =
  | {
      type: 'a',
      name: string;
      link: string;
    }
  | {
      type: 'b',
      name: string;
      children: NavDataItem[];
    };
Ответ написан
Комментировать
@awenn2015 Автор вопроса
Веб-программист самоучка
Всем спасибо за ответы, решить проблему конечно в тот момент конечно пришлось банально просто объединив перегрузки с оператором ? но ваши ответы дали понять почему по другому не работало, спасибо
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

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

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