جاوااسکریپت - Material-UI: چگونه یک نوع برای React.ComponentType

با تایپاسکریپت اعلام کنیم


من دارم از Typescript و Material-UI استفاده میکنم و میخواهم نوع کامپوننت را برای یک متغیر به این شکل اعلام کنم

import MoreVert from '@material-ui/icons/MoreVert'
import { SvgIconProps } from '@material-ui/core/SvgIcon';

let myIcon: SvgIconProps = <MoreVert />; // does not work

اما من با خطا مواجه میشوم:

[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'.

این به این صورت است که SvgIcon.ts به نظر میرسد. من کجا اشتباه میکنم؟

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;

پاسخ شماره ۱

مرجع: https://www.typescriptlang.org/docs/handbook/jsx.html

به طور پیشفرض، نتیجه یک عبارت JSX به صورت any تایپ میشود. شما میتوانید نوع را با مشخص کردن اینترفیس JSX.Element سفارشی کنید. با این حال، امکان بازیابی اطلاعات نوع درباره عنصر، صفات یا فرزندان JSX از این اینترفیس وجود ندارد. این یک جعبه سیاه است.

دلیل اینکه من تمام اطلاعات نوع را با JSX.Element از دست میدهم این است که این نوع از React.ReactElement<any> گسترش یافته است که نوع آن any است. برای رفع این مشکل، من از آن به این شکل استفاده کردم

 let myIcon: React.ReactElement<SvgIconProps> = <MoreVert />; 

حالا من عنصر را با تمام اطلاعات نوع آن دارم.

پاسخ شماره ۲

اگر رویکرد شخصی با روش مورد استفاده برای پاسخ به سؤال @Murat Karagöz کار نمیcکند، میcتوانید این کار را هنگام تنظیم اولیه یک مؤلفه یا متغیر از Icons در Material UI با استفاده از TypeScript امتحان کنید.

من با این روش درستش کردم که به این صورت اعلام کردم:

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',
  },
...
];

مرجع: [اسناد و نوعها] وارد کردن آیکونها از @material-ui/icons در TypeScript #647