写react一些前置条件
- 使用文件后缀 .tsx(替代 .ts);
- 在你的 tsconfig.json 配置文件的 compilerOptions 里设置选项 “jsx”: “react”;
- 在你的项目里为 JSX 和 React 安装声明文件:npm i -D @types/react @types/react-dom;
- 导入 react 到你的 .tsx 文件(import * as React from ‘react’)。
函数式组件
type Props = {
foo: string;
};
const MyComponent: React.FunctionComponent<Props> = props => {
return <span>{
props.foo}</span>;
};
<MyComponent foo="bar" />;
类组件
根据组件的 props 属性对组件进行类型检查。这是以 JSX 如何转换作为蓝本,例如:属性成为 props 的组成部分。
react.d.ts 文件定义了 React.Component<Props,State>,你应该使用自己所需的 Props 和 State 声明扩展它:
type Props = {
foo: string;
};
class MyComponent extends React.Component<Props, {
}> {
render() {
return <span>{
this.props.foo}</span>;
}
}
<MyComponent foo="bar" />;
React JSX Tip: 接收组件的实例
react 类型声明文件提供了 React.ReactElement,它可以让你通过传入 ,来注解类组件的实例化结果。
class MyAwesomeComponent extends React.Component {
render() {
return <div>Hello</div>;
}
}
const foo: React.ReactElement<MyAwesomeComponent> = <MyAwesomeComponent />; // Okay
const bar: React.ReactElement<MyAwesomeComponent> = <NotMyAwesomeComponent />; // Error!
案例:
import React from 'react';
interface IconProps{
name: string;
}
const Icon: React.FunctionComponent<IconProps> // React.FunctionComponent为对icon组件的类型测试,后面是传入的值的类型
=({
name, ...restProps})=> {
return (
<svg {
...restProps}>
<use xlinkHref={
`#${
name}`}/>
</svg>
);
};
export default Icon;
React JSX tip: 泛型组件
// 一个泛型组件
type SelectProps<T> = {
items: T[] };
class Select<T> extends React.Component<SelectProps<T>, any> {
}
// 使用
const Form = () => <Select<string> items={
['a', 'b']} />;
泛型函数
function foo<T>(x: T): T {
return x;
}
然而不能使用箭头泛型函数:
const foo = <T>(x: T) => T; // Error: T 标签没有关闭
解决办法:在泛型参数里使用 extends 来提示编译器,这是个泛型:
const foo = <T extends {
}>(x: T) => x;
React Tip: 强类型的 Refs
基本上你在初始化一个变量时,使用 ref 和 null 的联合类型,并且在回调函数中初始化他:
class Example extends React.Component {
example() {
// ... something
}
render() {
return <div>Foo</div>;
}
}
class Use {
exampleRef: Example | null = null;
render() {
return <Example ref={
exampleRef => (this.exampleRef = exampleRef)} />;
}
}
使用原生元素时也一样:
class FocusingInput extends React.Component<{
value: string; onChange: (value: string) => any }, {
}> {
input: HTMLInputElement | null = null;
render() {
return (
<input
ref={
input => (this.input = input)}
value={
this.props.value}
onChange={
e => {
this.props.onChange(e.target.value);
}}
/>
);
}
focus() {
if (this.input != null) {
this.input.focus();
}
}
}
类型断言
如我们之前提到的,可以使用 as Foo 语法进行类型断言
默认 Props
在有状态组件中使用默认的 Props:你可以通过 null 操作符(这不是一个理想的方式,但是这是我能想到的最简单的最小代码解决方案)告诉 TypeScript 一个属性将会被外部提供(React)。
class Hello extends React.Component<{
/**
* @default 'TypeScript'
*/
compiler?: string;
framework: string;
}> {
static defaultProps = {
compiler: 'TypeScript'
};
render() {
const compiler = this.props.compiler!;
return (
<div>
<div>{
compiler}</div>
<div>{
this.props.framework}</div>
</div>
);
}
}
ReactDOM.render(
<Hello framework="React" />, // TypeScript React
document.getElementById('root')
);
在 SFC 中使用默认的 Props:推荐使用简单的 JavaScript 参数,因为同样适用于 TypeScript 类型系统:
const Hello: React.SFC<{
/**
* @default 'TypeScript'
*/
compiler?: string;
framework: string;
}> = ({
compiler = 'TypeScript', // Default prop
framework
}) => {
return (
<div>
<div>{
compiler}</div>
<div>{
framework}</div>
</div>
);
};
ReactDOM.render(
<Hello framework="React" />, // TypeScript React
document.getElementById('root')
);