TypeScript 是一种向 JavaScript 代码添加类型定义的常用方法。简单来理解就是JS是一种弱类型的语言,当代码比较复杂时会比较容易出错,所以定义了TypeScript添加了一些源码上的约定。
TypeScript安装
所有的React框架基本全部支持,但不同的的框架比如Expo等的安装方式不太一样。使用下面命令安装最新版本的 React 类型定义
npm install @types/react @types/react-dom
每个包含 JSX 的文件都必须使用 .tsx 文件扩展名。这是一个 TypeScript 特定的扩展,告诉 TypeScript 该文件包含 JSX。
React中的关键语法
描述组件的 props 类型
function MyButton({ title }: { title: string }) {
return (
<button>{title}</button>
);
}
export default function MyApp() {
return (
<div>
<h1>欢迎来到我的应用</h1>
<MyButton title="我是一个按钮" />
</div>
);
}
使用 interface 描述组件的 props
当参数过多时也可以这样描述,但感觉不是太好,代码量有点大,而且非常耦合。
interface MyButtonProps {
/** 按钮文字 */
title: string;
/** 按钮是否禁用 */
disabled: boolean;
}
function MyButton({ title, disabled }: MyButtonProps) {
return (
<button disabled={disabled}>{title}</button>
);
}
export default function MyApp() {
return (
<div>
<h1>Welcome to my app</h1>
<MyButton title="我是一个禁用按钮" disabled={true}/>
</div>
);
}
Hook 使用
useState
- 显式设置类型
const [enabled, setEnabled] = useState(false);
// 显式设置类型为 "boolean"
const [enabled, setEnabled] = useState<boolean>(false);
- 使用type定义取值范围
type Status = "idle" | "loading" | "success" | "error";
const [status, setStatus] = useState<Status>("idle");
或
type RequestState =
| { status: 'idle' }
| { status: 'loading' }
| { status: 'success', data: any }
| { status: 'error', error: Error };
const [requestState, setRequestState] = useState<RequestState>({ status: 'idle' });
useReducer
详细见注释,共4个地方使用。
import {useReducer} from 'react';
//interface State 描述了 reducer state 的类型。
interface State {
count: number
};
//type CounterAction 描述了可以 dispatch 至 reducer 的不同 action。
type CounterAction =
| { type: "reset" }
| { type: "setCount"; value: State["count"] }
//为初始 state 提供类型,并且也将成为 useReducer 默认使用的类型。
const initialState: State = { count: 0 };
//State 设置了 reducer 函数参数和返回值的类型
function stateReducer(state: State, action: CounterAction): State {
switch (action.type) {
case "reset":
return initialState;
case "setCount":
return { ...state, count: action.value };
default:
throw new Error("Unknown action");
}
}
export default function App() {
const [state, dispatch] = useReducer(stateReducer, initialState);
const addFive = () => dispatch({ type: "setCount", value: state.count + 5 });
const reset = () => dispatch({ type: "reset" });
return (
<div>
<h1>欢迎来到我的计数器</h1>
<p>计数: {state.count}</p>
<button onClick={addFive}>加 5</button>
<button onClick={reset}>重置</button>
</div>
);
}
useContext
import { createContext, useContext, useState, useMemo } from 'react';
// 这是一个简单的示例,但你可以想象一个更复杂的对象
type ComplexObject = {
kind: string
};
// 上下文在类型中创建为 `| null`,以准确反映默认值。
const Context = createContext<ComplexObject | null>(null);
// 这个 Hook 会在运行时检查 context 是否存在,并在不存在时抛出一个错误。
const useGetComplexObject = () => {
const object = useContext(Context);
if (!object) { throw new Error("useGetComplexObject must be used within a Provider") }
return object;
}
export default function MyApp() {
const object = useMemo(() => ({ kind: "complex" }), []);
return (
<Context.Provider value={object}>
<MyComponent />
</Context.Provider>
)
}
function MyComponent() {
const object = useGetComplexObject();
return (
<div>
<p>Current object: {object.kind}</p>
</div>
)
}
React元素
Event元素
在 React 中处理 DOM 事件时,事件的类型通常可以从事件处理程序中推断出来。但是,当你想提取一个函数以传递给事件处理程序时,你需要明确设置事件的类型。React.ChangeEvent等完整的事件列表可查看此链接
import { useState } from 'react';
export default function Form() {
const [value, setValue] = useState("Change me");
//注意看下这行
function handleChange(event: React.ChangeEvent<HTMLInputElement>) {
setValue(event.currentTarget.value);
}
return (
<>
<input value={value} onChange={handleChange} />
<p>值: {value}</p>
</>
);
}
Dom元素
ReactNode可以在 JSX 中作为子元素传递的所有可能类型的并集。
interface ModalRendererProps {
title: string;
children: React.ReactNode;
}
style元素
interface MyComponentProps {
style: React.CSSProperties;
}