为什么类型 SFC<AnchorProps>不能分配到类型 SFC<{}>? [英] Why is type SFC<AnchorProps> not assignable to type 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屋!