为什么类型 SFC<AnchorProps>不能分配到类型 SFC<{}>? [英] Why is type SFC&lt;AnchorProps&gt; not assignable to type SFC&lt;{}&gt;?

查看:71
本文介绍了为什么类型 SFC<AnchorProps>不能分配到类型 SFC<{}>?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下代码在被 TypeScript 编译时抛出错误.

The following code throws an error when it’s compiled by TypeScript.

import React, { SFC } from "react"
import { Link } from "react-router-dom"
import { HashLink } from "react-router-hash-link"
import MarkdownToJSX from "markdown-to-jsx"

interface AnchorProps {
  baseUrl: string
  relativeUrl: string
  href: string
}

const Anchor: SFC<AnchorProps> = function(props) {
  /*
  FYI, props.baseUrl and props.relativeUrl is used by code I didn’t include in
  this example to keep things simple.
  */
  if (
    props.href.match(/^http(s)?:\/\//) ||
    props.href.match(/^mailto:/) ||
    props.href.match(/^tel:/)
  ) {
    return (
      <a href={props.href} rel="noopener noreferrer" target="_blank">
        {props.children}
      </a>
    )
  } else if (props.href.match(/^#/)) {
    return (
      <HashLink to={props.href} smooth>
        {props.children}
      </HashLink>
    )
  } else {
    return <Link to={props.href}>{props.children}</Link>
  }
}

const Markdown = function() {
  return (
    <MarkdownToJSX
      options={{
        overrides: {
          a: {
            component: Anchor,
            props: {
              baseUrl: "/privacy-guides",
              relativeUrl: "",
            },
          },
        },
      }}
    >
      # This is [markdown](markdown)
    </MarkdownToJSX>
  )
}

export default Markdown

/Users/sunknudsen/Sites/sunknudsen/sunknudsen-website/src/Test.tsx
TypeScript error in /Users/sunknudsen/Sites/sunknudsen/sunknudsen-website/src/Test.tsx(40,13):
No overload matches this call.
  Overload 1 of 2, '(props: Readonly<MarkdownProps>): Markdown', gave the following error.
    Type 'FunctionComponent<AnchorProps>' is not assignable to type 'string | SFC<{}> | ComponentClass<{}, any>'.
      Type 'FunctionComponent<AnchorProps>' is not assignable to type 'SFC<{}>'.
        Types of parameters 'props' and 'props' are incompatible.
          Type '{ children?: ReactNode; }' is not assignable to type 'PropsWithChildren<AnchorProps>'.
            Type '{ children?: ReactNode; }' is missing the following properties from type 'AnchorProps': baseUrl, relativeUrl, href
  Overload 2 of 2, '(props: MarkdownProps, context?: any): Markdown', gave the following error.
    Type 'FunctionComponent<AnchorProps>' is not assignable to type 'string | SFC<{}> | ComponentClass<{}, any>'.
      Type 'FunctionComponent<AnchorProps>' is not assignable to type 'SFC<{}>'.  TS2769

    38 |         overrides: {
    39 |           a: {
  > 40 |             component: Anchor,
       |             ^
    41 |             props: {
    42 |               baseUrl: "/privacy-guides",
    43 |               relativeUrl: "",

我不明白为什么.

推荐答案

这似乎是 markdown-to-jsx 类型定义的限制.

This seems to be a limitation of the markdown-to-jsx type definitions.

具体来说,MarkdownToJSX.options.overrides 属于 ComponentOverride 类型,而 ComponentOverride 属于这种类型:

Specifically, The MarkdownToJSX.options.overrides is of type ComponentOverride, and the ComponentOverride is of this type:

export type ComponentOverride = string | React.ComponentClass | React.SFC | {
    component: string | React.ComponentClass | React.SFC;
    props?: any;
};

该类型不允许您将泛型参数传递给 React.SFC,这意味着它采用其默认的泛型参数:

That type does not let you pass a generic parameter to React.SFC, which means that it takes its default generic parameter:

type SFC<P = {}> = FunctionComponent<P>;

该默认泛型参数是一个空对象 {}.

That default generic parameter is an empty object {}.

由于您的代码试图将 AnchorProps 类型分配给空对象类型,因此编译器会抱怨.

Since your code is trying to assign an AnchorProps type to an empty object type, the compiler is complaining.

这在运行时是否会成为问题取决于底层 JavaScript 在运行时的工作方式.像这样投射可能没问题:

Whether this is going to be a problem at runtime depends on how the underlying JavaScript works at runtime. It might be fine to cast like this:

const Markdown = function() {
  return (
    <MarkdownToJSX
      options={{
        overrides: {
          a: {
            component: Anchor,
            props: {
              baseUrl: "/privacy-guides",
              relativeUrl: ""
            }
            // We have tested that this works at runtime,
            // we we know more than the compiler knows.
          } as ComponentOverride
        }
      }}
    >
      # This is [markdown](markdown)
    </MarkdownToJSX>
  );
};

这篇关于为什么类型 SFC<AnchorProps>不能分配到类型 SFC<{}>?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆