本文根据日常开发实践,参考优秀文章、文档,来说说 TypeScript
是如何较优雅的融入 React
项目的。
温馨提示:日常开发中已全面拥抱函数式组件和 React Hooks
,class
类组件的写法这里不提及。
import React, {
useState } from 'react';
// 以后将被替代成
import {
useState } from 'react';
import * as React from 'react';
type BasicTypes = {
message: string;
count: number;
disabled: boolean;
names: string[]; // or Array
id: string | number; // 联合类型
}
一般的联合类型,没什么好说的,这里提一下非常有用,但新手经常遗忘的写法 —— 字符字面量联合。
ajax
时,一般 method
就那么具体的几种:get
、post
、put
等。string
型,你可能会这么写:type UnionsTypes = {
method: string; // ❌ bad,可以传入任意字符串
};
type UnionsTypes = {
method: 'get' | 'post'; // ✅ good 只允许 'get'、'post' 字面量
};
type ObjectTypes = {
obj3: {
id: string;
title: string;
};
objArr: {
id: string;
title: string;
}[]; // 对象数组,or Array<{ id: string, title: string }>
};
type ObjectTypes = {
obj: object; // ❌ bad,不推荐
obj2: {
}; // ❌ bad 几乎类似 object
};
Record
。type ObjectTypes = {
objBetter: Record<string, unknown>; // ✅ better,代替 obj: object
// 对于 obj2: {}; 有三种情况:
obj2Better1: Record<string, unknown>; // ✅ better 同上
obj2Better2: unknown; // ✅ any value
obj2Better3: Record<string, never>; // ✅ 空对象
/** Record 更多用法 */
dict1: {
[key: string]: MyTypeHere;
};
dict2: Record<string, MyTypeHere>; // 等价于 dict1
};
参考React实战视频讲解:进入学习
Record
有什么好处呢,先看看实现:// 意思就是,泛型 K 的集合作为返回对象的属性,且值类型为 T
type Record<K extends keyof any, T> = {
[P in K]: T;
};
interface PageInfo {
title: string;
}
type Page = 'home' | 'about' | 'contact';
const nav: Record<Page, PageInfo> = {
about: {
title: 'about' },
contact: {
title: 'contact' },
// TS2322: Type '{ about: { title: string; }; contact: { title: string; }; hoem: { title: string; }; }'
// is not assignable to type 'Record'. ...
hoem: {
title: 'home' },
};
nav.about;
好处:
home
值时,键入 h
常用的编辑器有智能补全提示;home
拼写错误成 hoem
,会有错误提示,往往这类错误很隐蔽;Function
类型,有明确的参数类型、个数与返回值类型最佳。type FunctionTypes = {
onSomething: Function; // ❌ bad,不推荐。任何可调用的函数
onClick: () => void; // ✅ better ,明确无参数无返回值的函数
onChange: (id: number) => void; // ✅ better ,明确参数无返回值的函数
onClick(event: React.MouseEvent<HTMLButtonElement>): void; // ✅ better
};
type OptionalTypes = {
optional?: OptionalType; // 可选属性
};
name
,age
是你新增的属性,age
可选,other
为第三方的属性集。type AppProps = {
name: string;
age?: number;
[propName: string]: any;
};
const YourComponent = ({
name, age, ...other }: AppProps) => (
<div>
{
`Hello, my name is ${
name}, ${
age || 'unknown'}`<