I am using Typescript and Material-UI I want to declare the component type for a variable like this
import MoreVert from '@material-ui/icons/MoreVert'
import { SvgIconProps } from '@material-ui/core/SvgIcon';
let myIcon: SvgIconProps = <MoreVert />; // does not work
But I am getting the error:
[ts]
Type 'Element' is not assignable to type 'SvgIconProps'.
Types of property 'type' are incompatible.
Type 'string | ComponentClass<any> | StatelessComponent<any>' is not assignable to type 'string'.
Type 'ComponentClass<any>' is not assignable to type 'string'.
This is how the SvgIcon.ts looks like. What am I doing wrong?
import * as React from 'react';
import { StandardProps, PropTypes } from '..';
export interface SvgIconProps
extends StandardProps<React.SVGProps<SVGSVGElement>, SvgIconClassKey> {
color?: PropTypes.Color | 'action' | 'disabled' | 'error';
component?: React.ReactType<SvgIconProps>;
fontSize?: 'inherit' | 'default' | 'small' | 'large';
nativeColor?: string;
titleAccess?: string;
viewBox?: string;
}
export type SvgIconClassKey =
| 'root'
| 'colorSecondary'
| 'colorAction'
| 'colorDisabled'
| 'colorError'
| 'colorPrimary'
| 'fontSizeInherit'
| 'fontSizeSmall'
| 'fontSizeLarge';
declare const SvgIcon: React.ComponentType<SvgIconProps>;
export default SvgIcon;
Reference: https://www.typescriptlang.org/docs/handbook/jsx.html
By default the result of a JSX expression is typed as any. You can customize the type by specifying the JSX.Element interface. However, it is not possible to retrieve type information about the element, attributes or children of the JSX from this interface. It is a black box.
The reason why I lose all type information with JSX.Element
is because it extends React.ReactElement<any>
which has the type of any
. To fix this I used it like this
let myIcon: React.ReactElement<SvgIconProps> = <MoreVert />;
Now I have the element with all the type information.
As already briefly described by Ebuall in a comment, here's how you would declare the variable depending on whether you want the JSX element or the component type:
let myIconElement: JSX.Element = <MoreVert />;
let MyIconComponent: React.ComponentType<SvgIconProps> = MoreVert;
// Example component that uses the icon
function myComponent(props: {}) {
return <>
{myIconElement}
{<MyIconComponent />}
</>;
}
If anyone does not work by the way answered question of @Murat Karagöz you may try this when initializing an interface or a variable of an Icons from Material UI using TypeScript.
I got this working by declaring like this:
import ShowChartIconOutlined from '@material-ui/icons/ShowChartOutlined'; import { SvgIconProps } from '@material-ui/core'; type Menu = { id: number; icon: (props: SvgIconProps) => JSX.Element; label: string; }[]; const NavBarMenus: Menu = [ { id: 1, icon: ShowChartIconOutlined, label: 'Dashboard', }, ... ];
Reference: [Docs & Types] Importing icons from @material-ui/icons in TypeScript #647
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With