Хорошо, спасибо Lombas и aquz за то, что указали мне правильное направление.Как и много раз раньше, я пытался упростить свою проблему, чтобы поделиться ею здесь, и при этом я упрощал ее.
Моя более точная проблема заключалась в следующей структуре:
export type NavigationEntry = NavigationEntryWithChildren | NavigationEntryWithoutChildren;
interface NavigationEntryBase {
display: string;
exact?: boolean;
}
interface NavigationEntryWithChildren extends NavigationEntryBase {
children: NavigationEntry[];
}
interface NavigationEntryWithoutChildren extends NavigationEntryBase {
routerLinkInfo: any[] | string;
}
КакНазвание указывает, что речь идет о создании навигационной структуры.На любом уровне, у вас есть URL (routerLinkInfo
) или , у вас есть дети.Поэтому мне пришлось использовать типы union , а не просто интерфейсы.
Хотя я занимаюсь TypeScript полный рабочий день в течение 3 лет, мой ум иногда застревает в более традиционном объектно-ориентированном типетакие системы, как C #, и забывают, что TypeScript просто заставит его работать .
Так что вместо того, чтобы возиться с NavigationEntry
и заставить его работать напрямую, я создал несколько дополнительных типов:
interface CustomNavigationEntryWithChildren<T> extends NavigationEntryWithChildren {
children: CustomNavigationEntry<T>[];
}
export type CustomNavigationEntry<T> =
| (CustomNavigationEntryWithChildren<T> & T)
| (NavigationEntryWithoutChildren & T);
При таком подходе весь существующий код, для которого требуется только NavigationEntry
, будет работать.А более новые проекты, которые хотят добавить дополнительные свойства в свои узлы навигации, могут делать это следующим образом:
type Foo = CustomNavigationEntry<{foo: boolean}>;
В приведенном выше примере все узлы должны иметь логическое значение foo
.
Надеюсь, что это поможет следующему человеку (даже если это только я;))