All*_*lan 4 typescript reactjs styled-components
我有这样的组件
import React from 'react';
import styled from '../../styled-components';
const StyledInput = styled.input`
display: block;
padding: 5px 10px;
width: 50%;
border: none;
border-radius: 10px;
outline: none;
background: ${(props) => props.theme.color.background};
font-family: 'Roboto', sans-serif;
`
;
export const Input = () => {
return <StyledInput placeholder="All notes"></StyledInput>
}
Run Code Online (Sandbox Code Playgroud)
我想像这样将它们作为属性放在“索引”组件上
import styled from 'styled-components';
import { Input } from './Input';
const NoteTags:any = styled.div`
display: flex;
justify-content: space-between;
align-items: center;
width: 20%;
height: 5%;
border-bottom: 2px solid ${(props) => props.theme.color.background}; `;
NoteTags.Input = Input;
export default NoteTags;
Run Code Online (Sandbox Code Playgroud)
那么我可以像这样使用它们
import React from 'react';
import NoteTags from '../../blocks/note-tags';
const ComponentNoteTags = () => {
return (
<React.Fragment>
<NoteTags.Input></NoteTags.Input>
</React.Fragment>
)
}
export default ComponentNoteTags;
Run Code Online (Sandbox Code Playgroud)
问题是该属性Input不存在,NoteTags 所以打字稿给了我一个错误。我可以通过将 type 设置为any来解决它,NoteTags但我不确定这是最好的方法。
有没有更好的方法来修复它?
更新
我发现使用类型助手将额外的属性添加到组件的变量中要好得多:
// type-helper.ts
export function withProperties<A, B>(component: A, properties: B): A & B {
Object.keys(properties).forEach(key => {
component[key] = properties[key]
});
return component as A & B;
}
Run Code Online (Sandbox Code Playgroud)
注意:@Allan 在评论中指出,类型断言可能是必要的,如下所示:
Run Code Online (Sandbox Code Playgroud)(component as any)[key] = (properties as any)[key]避免打字稿抱怨
Element implicitly has an 'any' type because type '{}' has no index signature.
我们只是将每个属性传递properties给component并给它一个两者的连接类型。然后我们可以将子组件“粘合”到主组件中,如下所示:
// component/index.ts
import MainComponent from './MainComponent';
import SubComponent1 from './SubComponent1';
import SubComponent2 from './SubComponent2';
import { withProperties } from '../type-helper.ts';
export withProperties(MainComponent, { SubComponent1, SubComponent2 })
Run Code Online (Sandbox Code Playgroud)
并像往常一样使用它
import MainComponent from './Component';
export default () => (
<MainComponent>
<SubComponent1 />
<SubComponent2 />
</MainComponent>
)
Run Code Online (Sandbox Code Playgroud)
这种方法也适用于普通的 React 组件,而不仅仅是样式组件,所以我认为它更好。
上一个答案
假设您使用的是最新的软件包:
"styled-components": "^4.1.3",
"@types/styled-components": "^4.1.10",
Run Code Online (Sandbox Code Playgroud)
您可以创建一个包含父组件和子组件类型的交互类型:
import styled, { StyledComponent } from 'styled-components'
import ChildComponent from '...'
type Component = StyledComponent<'div', any> & {
ChildComponent: /* your component type */
}
interface IProps {
...
}
// create styled component per usual
const MyComponent = styled.div<IProps>`
...
` as Component
MyComponent.ChildComponent = ChildComponent;
Run Code Online (Sandbox Code Playgroud)
export type StyledComponent<
C extends keyof JSX.IntrinsicElements | React.ComponentType<any>,
T extends object, // theme interface
O extends object = {}, // props interface
A extends keyof any = never
> = string & StyledComponentBase<C, T, O, A>;
Run Code Online (Sandbox Code Playgroud)
您可以将其用作StyledComponent<C, T, O, A>或StyledComponent<C, T>
| 归档时间: |
|
| 查看次数: |
5090 次 |
| 最近记录: |