Open JNUfeatherwit opened 2 years ago
反例:
interface IProps{ text: any; onClick:()=>any }
正例:
interface IProps{ text: string; onClick:()=>void }
function get ( url: string, params?: any, ): Promise<any> { return this.request({ method: 'get', url: this.getApiUrl(url, params), }); }; // 无法做出入参类型校验
正例:
function get<P,R> ( url: string, params?: P, ): Promise<R> { return request({ method: 'get', url: this.getApiUrl(url, params), }) as R; }; // 使用 get<IParams,IResult>(url,{})
export const sleep = (time = 500,arg1:number,arg2?:number) => { return new Promise<void>((resolve, reject) => { setTimeout(() => { resolve(); }, time); }); };
1、object类型 只可使用interface关键字,命名前缀加“I”代表是interface类型 正例:
interface IObject { [key: string]: any; } interface IRequestOptions { method?: string; data?: IObject; headers?: IObject; url?: string; [key: string]: any; }
注意: 服务端接口的入参类型如果为object类型,需使用服务端的类型/实体类名称来命名,格式为'I'+【类型名称】,防止多个接口使用同一个实体类时前端维护多个不同名称的类型; 如果是入参,命名则是“I”+【接口名称驼峰】+"Params" 正例:
// 入参 interface IUpdateBusinessInfoParams { id: string; highInsuranceExpires?: number; commercialInsuranceExpires?: number; nextAnnual?: number; nextMaintain?: number; } // 出参 interface IStdName { categoryCode: string; categoryName: string; stdName: string; stdNameCode: string; }
如何知道服务端提供的类型名称:
2、enum枚举类型 使用enum关键字,如果含义是xx类型时命名后缀需加“Type”;key只能为string类型,且首字母大写,驼峰式命名
export enum ModeType { JsModal = 'js-modal', RnModal = 'rn-modal', ToolTip = 'tooltip' }
魔鬼数字的定义:在代码中没有具体含义的数字、字符串,影响代码可读性,读者看到的数字无法理解其含义,从而难以理解程序的意图 如何解决:使用enum或者对象定义枚举,优先使用enum
反例:
if(type===1){ console.log('HOUR') }
enum TimeType{ HOUR=1, SECONDS=2, } if(type===TimeType.HOUR){ console.log('HOUR') }
(1)全局类型
在src目录下新建typings文件夹,如果是export方式,后缀为.ts;如果是declare方式,后缀为.d.ts
└── typings ├── common.ts ├── big.d.ts
注意一下declare,declare是用来全局声明一个变量、模块、类型、作用域,用来告诉TS编译器你担保这些变量和模块存在,并声明了相应类型,在项目里可直接使用这些全局属性,不需要import
declare module 'foo' { export interface Foo { foo: string; } } declare module 'bar' { export function bar(): string; } / src/index.ts import { Foo } from 'foo'; import * as bar from 'bar'; let f: Foo; bar.bar();
(2) 接口相关类型
接口文件结构(分为接口的定义和类型的定义) └── api ├── store.ts ├── car.ts └── typings ├── store.ts ├── car.ts
export async function getCustomerCarList( params: ISearchParams, ){ return await requestWrapper<ISearchParams, IPaged<ICarInfo>>( Http.get, '/saas-api/customer/car/list', params, ); }
export interface ISearchParams { keyword?: string; pageNum?: number; pageSize?: number; } export interface ICarInfo { id?: string; carType: number; carNo: string; }
(3) 其他情况 定义typings.ts文件
1、联合类型、交叉类型
A|B // 要求类型满足A或B A&B //要求类型同时满足A和B
2、类型的泛型
// 分页类型 export interface IPaged<T> { list: T[]; pageNum: number; hasNextPage: boolean; pageSize: number; pages?: number; size?: number; total: number; }
3、一些内置的常用的工具泛型
interface IData{ name:string; count:string; } Partial<IData> /* { name?:string; count?:string; } */
function getInt(a: string) { return parseInt(a); }
type A = ReturnType; // => number
- Record : 定义对象的key和value
interface PageInfo { title: string; }
type Page = "home" | "about" | "contact";
const nav: Record<Page, PageInfo> = { about: { title: "about" }, contact: { title: "contact" }, home: { title: "home" }, };
学到了,谢谢大佬
基本原则
1、any类型少用或不用
反例:
正例:
2、使用泛型,使得类型的确定时机置于使用时
反例:
正例:
3、函数入参需写类型,有默认值可以不写,可选参数置于右边,出参根据情况可写可不写
4、类型的命名
1、object类型 只可使用interface关键字,命名前缀加“I”代表是interface类型 正例:
注意: 服务端接口的入参类型如果为object类型,需使用服务端的类型/实体类名称来命名,格式为'I'+【类型名称】,防止多个接口使用同一个实体类时前端维护多个不同名称的类型; 如果是入参,命名则是“I”+【接口名称驼峰】+"Params" 正例:
如何知道服务端提供的类型名称:
2、enum枚举类型 使用enum关键字,如果含义是xx类型时命名后缀需加“Type”;key只能为string类型,且首字母大写,驼峰式命名
5、避免出现"魔鬼数字"
魔鬼数字的定义:在代码中没有具体含义的数字、字符串,影响代码可读性,读者看到的数字无法理解其含义,从而难以理解程序的意图 如何解决:使用enum或者对象定义枚举,优先使用enum
反例:
正例:
6、类型较多时或者需要给其他文件用时,需要建立typings.ts文件来专门定义类型文件,防止出现循环引用
(1)全局类型
在src目录下新建typings文件夹,如果是export方式,后缀为.ts;如果是declare方式,后缀为.d.ts
└── typings ├── common.ts ├── big.d.ts
注意一下declare,declare是用来全局声明一个变量、模块、类型、作用域,用来告诉TS编译器你担保这些变量和模块存在,并声明了相应类型,在项目里可直接使用这些全局属性,不需要import
(2) 接口相关类型
接口文件结构(分为接口的定义和类型的定义) └── api ├── store.ts ├── car.ts └── typings ├── store.ts ├── car.ts
(3) 其他情况 定义typings.ts文件
7、类型的扩展
1、联合类型、交叉类型
2、类型的泛型
3、一些内置的常用的工具泛型
type A = ReturnType; // => number
interface PageInfo { title: string; }
type Page = "home" | "about" | "contact";
const nav: Record<Page, PageInfo> = { about: { title: "about" }, contact: { title: "contact" }, home: { title: "home" }, };