Reactjs 带有样式化组件的TypeScript

Reactjs 带有样式化组件的TypeScript,reactjs,typescript,styled-components,Reactjs,Typescript,Styled Components,这里是打字新手。我有一个下面使用样式化组件的组件,我想将其转换为TypeScript import React from 'react' import PropTypes from 'prop-types' import styled from 'styled-components' const propTypes = { name: PropTypes.string.isRequired // https://material.io/tools/icons/?style=baselin

这里是打字新手。我有一个下面使用
样式化组件的组件
,我想将其转换为
TypeScript

import React from 'react'
import PropTypes from 'prop-types'
import styled from 'styled-components'


const propTypes = {
  name: PropTypes.string.isRequired // https://material.io/tools/icons/?style=baseline
}

const Icon = styled(({name, className, ...props}) => <i className={`material-icons ${className}`} {...props}>{name}</i>)`
  font-size: ${props => props.theme.sizeLarger};
`

Icon.propTypes = propTypes

export default Icon
然而,TypeScript抱怨我未声明
className
。问题是,理想情况下,我希望使用
接口
作为开发人员可以提供的一种道具规范,而不必声明像
类名
主题
这样的道具,它们是由
样式化组件
之类的库注入的

如何正确地将此组件转换为TypeScript?

从“React”导入React;
从“样式化组件”导入样式化;
界面道具{
名称:字符串;
类名?:字符串;
}
const NonStyledIcon:React.SFC=({name,className,…props})=>(
{name}
);
常量图标=已设置样式(非样式化图标)`
字体大小:${props=>props.theme.sizeLarger};
`;
导出默认图标;

根据样式化组件:定义组件时,您需要在Props界面中将className标记为可选

除非您在这样的地方增加了主题的内部类型,否则props.theme不会正确地键入

declare module "styled-components" {
    /* tslint:disable */
    export interface DefaultTheme extends YourThemeInterfaceType {}
}
这将把props.theme的类型更改为YourThemeInterfaceType,前提是您正确地遵循了增强文档,但不能创建一个styled-components.d.ts文件,并将其更改为您的tsconfig

"include": [
    "src/**/*"
],
接下来,您需要知道参数的类型“name”是一个字符串,className也是一个可选的字符串,我假设用一个可选的字符串来实现这一点,只需将上面的内容重写为这个

interface IIconProps {
    name: string;
    className?: string;
};

const Icon = styled(({name, className, ...props}: IIconProps) => <i className={`material-icons ${className}`} {...props}>{name}</i>)`
    font-size: ${props => props.theme.sizeLarger};
`;


const test = <Icon name={"xyz"} className={"xyz"}/> // passes typecheck.
接口IIconProps{
名称:字符串;
类名?:字符串;
};
const Icon=styled({name,className,…props}:IIconProps)=>{name})`
字体大小:${props=>props.theme.sizeLarger};
`;
const test=//通过类型检查。
希望这有帮助


编辑:proptypes在typescript中也是不使用usless的。

这里有一个综合的方法,使用带有React Native的样式化组件v5,也可以使用普通React。如果没有使用主题,可以跳到底部的
StyledProps
部分

  • 定义你的主题类型

    //MyTheme.ts
    导出类型MyTheme={
    颜色:{
    主:字符串;
    背景:字符串;
    };
    };
    
  • 在主题上使用该类型

    //themes.ts
    导出常量LightTheme:MyTheme={
    颜色:{
    小学:“白色”,
    背景:“白色”,
    },
    };
    导出常量暗模式:神话模式={
    颜色:{
    初级:“灰色”,
    背景:“黑色”,
    },
    };
    
  • 用于将MyTheme类型“合并”到样式化组件默认主题中

    //styled.d.ts
    导入“样式化组件”;
    从“../src/themes/MyTheme”导入{MyTheme};
    声明模块“样式化组件”{
    //eslint禁用下一行@typescript eslint/无空接口
    导出接口DefaultTheme扩展MyTheme{}
    }
    
好的,酷。
主题
道具键入正确。
组件本身呢

  • 将特定组件道具包装在
    StyledProps
    类型中

    从“样式化组件”导入{StyledProps};
    从“样式化组件/本机”导入样式化;
    键入MyViewProps=StyledProps;
    const MyView=styled.View(
    (道具:MyViewProps)=>`
    背景色:${props.backgroundColor | | props.theme.colors.background};
    颜色:${props.isAlert?红色:props.theme.colors.primary}
    `,
    );
    

在本例中,
props.backgroundColor
props.theme.colors.background
将自动完成。当您更新MyTheme类型或特定组件类型时,它应该可以正常工作。陛下声明
className
感觉既多余又有误导性,不是吗?这会告诉组件的潜在用户,他们可能会设置一个
className
prop,在这种情况下,组件将无法按预期工作,对吗?我认为这是一个合理的反对意见,但这仍然是官方的做法,这很烦人。我认为在你增加风格的时候应该增加界面。它实际上对我帮助很大!!ThxUser注意:命名文件
样式化组件.d.ts
会导致它完全覆盖@types定义。相反,您应该将其命名为
styled.d.ts
,或者将声明与其他全局类型放在
index.d.ts
interface IIconProps {
    name: string;
    className?: string;
};

const Icon = styled(({name, className, ...props}: IIconProps) => <i className={`material-icons ${className}`} {...props}>{name}</i>)`
    font-size: ${props => props.theme.sizeLarger};
`;


const test = <Icon name={"xyz"} className={"xyz"}/> // passes typecheck.