【发布时间】:2020-01-27 03:52:24
【问题描述】:
我有一个功能组件Button,它使用一个道具as 来注入一个HTML 元素或另一个组件。我想将as 属性默认为react-router 的Link 组件。这将使Link 的to 道具成为Button 的强制道具。所以,我写<Button>Press me!</Button>的时候应该会报错,但是编译器没有报错。
我正在使用 typescript v3.5.3,在 tsconfig.json 中有以下设置:
{
"compilerOptions": {
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitThis": true,
"strictFunctionTypes": true,
"strictBindCallApply": true,
"alwaysStrict": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true
}
}
这是我目前的情况(简化),Link 作为as es6 样式的默认值:
import React from 'react'
import { Link } from 'react-router-dom'
interface ButtonProps {
children?: string
}
type ElementInjector<T extends React.ElementType> = {
as: T
} & React.ComponentPropsWithoutRef<T>
export const Button = <T extends React.ElementType>({
as: Tag = Link,
...props
}: ButtonProps & ElementInjector<T>) => {
return <Tag {...props} />
}
因此,鉴于上述情况,这是结果和期望:
<Button>Button</Button> // error - asking for `as` not `to`
<Button as={Link}>Button</Button> // error - ok
<Button to="/">Button</Button> // error - asking for `as`
<Button as="a">Button</Button> // success - ok
如何让第一个失败?
解决以下问题也很酷。与defaultProps 无关,但与通用方法有关。
<Button as="a" to="/">Button</Button> // success - error expected
<Button<'a'> as="a" to="/">Button</Button> // error - ok
【问题讨论】:
标签: reactjs typescript typescript-generics