最近,在做项目模块的迁移,新项目需要使用ts,遇到的问题有点多,记录一下。
先来复现一下场景:
import React from 'react';
type PersonProps = {
name: string;
age: number;
};
const Person = (props: PersonProps) => {
const { name, age } = props;
return (
<div>
<div>{`${name}: ${age}`}</div>
{/* Error: Property 'children' does not exist on type 'PersonProps'.ts(2339) */}
{props.children}
</div>
);
};
const App = () => {
return (
<div>
{/* Error: Property 'children' does not exist on type 'IntrinsicAttributes & PersonProps'.ts(2322) */}
<Person name="李四" age={26}>这是children哦</Person>
</div>
);
};
export default App;
出现这个报错的原因,是因为我们的props中并没有定义children类型,在PersonProps中加上该类型即可。
type PersonProps = {
name: string;
age: number;
children: React.ReactNode; // 添加children类型
};
如果我们的子组件不需要传递给Person组件,则无需定义children,因为不会用到。
import React from 'react';
type PersonProps = {
name: string;
age: number;
};
const Person = (props: PersonProps) => {
const { name, age } = props;
return (
<div>
<div>{`${name}: ${age}`}</div>
</div>
);
};
const App = () => {
return (
<div>
<Person name="张三" age={25} />
</div>
);
};
export default App;
除了上述的写法外,我们也可以通过解构的形式定义Person方法,代码如下:
const Person = ({ name, age }: PersonProps) => {
return (
<div>
<div>{`${name}: ${age}`}</div>
</div>
);
};
如果想跳过类型检查或者不知道属性的类型,也可以使用any,当然,这种做法并不推荐,这相当于没有用到ts,代码如下:
// 禁用类型检查
const Person = ({ name, age }: any) => {
return (
<div>
<div>{`${name}: ${age}`}</div>
</div>
);
};
除此之外,也可以通过ReactFunctionComponent泛型接口,props默认定义为{}
import React from 'react';
type PersonProps = {
name: string;
age: number;
};
const Person: React.FunctionComponent<PersonProps> = ({ name, age }) => {
return (
<div>
<div>{`${name}: ${age}`}</div>
</div>
);
};
const App = () => {
return (
<div>
<Person name="张三" age={25} />
</div>
);
};
export default App;
等同于下面的这个例子:
import React, { FC } from 'react';
type PersonProps = {
name: string;
age: number;
};
const Person: FC<PersonProps> = ({ name, age }) => {
return (
<div>
<div>{`${name}: ${age}`}</div>
</div>
);
};
const App = () => {
return (
<div>
<Person name="张三" age={25} />
</div>
);
};
export default App;
感兴趣的朋友可以看看源码:
type FC<P = {}> = FunctionComponent<P>;
interface FunctionComponent<P = {}> {
(props: PropsWithChildren<P>, context?: any): ReactElement<any, any> | null;
propTypes?: WeakValidationMap<P> | undefined;
contextTypes?: ValidationMap<any> | undefined;
defaultProps?: Partial<P> | undefined;
displayName?: string | undefined;
}
OK,本文到此结束,如有不足,欢迎大家多多指正呀!