Я делаю компонент высокого порядка (HOC) для @expo/vector-icons и пытаюсь определить общий тип его реквизита. Внутри модуля есть несколько источников иконок components (MaterialCommunityIcons, MaterialIcons, FontAwesome и т. д.), и все они имеют одинаковую форму, но уникальные литеральные типы для иконки names.
Итак, HOC должен получить два реквизита: источник component и значок name. Идея в том, что когда component определен, реквизит name должен выводить соответствующий список доступных имен для выбранного источника. Моя попытка выглядит так:
const IconLibs = { MaterialCommunityIcons, MaterialIcons, FontAwesome };
type IconLibsNames = keyof typeof IconLibs;
type HocProps<Key extends IconLibsNames> = {
component: typeof IconLibs[Key];
name: React.ComponentProps<typeof IconLibs[Key]>["name"];
};
В моем результате я вижу, что все names собираются в общий список и все они доступны для каждого источника component. Как их правильно разделить?
Если это было бы полезно, буквенный тип подходящего component names (например, "stop" | "forward" | "check" | "close" | "book" ...) можно было бы использовать двумя способами:
1.
type name = React.ComponentProps<typeof MaterialIcons>["name"]
type name = keyof typeof MaterialIcons.glyphMap
Я думаю, проблема в том, что вы пытались вывести имя, используя общий + typeof. Я бы рекомендовал использовать более простой подход:
const IconLibs = { MaterialCommunityIcons, MaterialIcons, FontAwesome };
type IconComponent = typeof IconLibs[keyof typeof IconLibs]
type HocProps<TComponent extends IconComponent> = {
component: TComponent;
name: React.ComponentProps<TComponent>['name']
};
const hoc = <TComponent extends IconComponent>({name, component}: HocProps<TComponent>) => {
// implementation of hoc
}
hoc({component: FontAwesome, name: '...'}) // `name` will be inferred from the FontAwesome
Работает отлично. Спасибо Плоский глобус. Осталось придумать как)))