TypeScript interface使用实践
你将学会
- 通过一个简单的例子来实践interface的用法,加深对interface的理解
面向对象
对TypeScript有一定掌握程,了解"鸭子类型",使用react技术栈的同学
难度系数
⭐⭐
正文
本文重点是interface的实践,不要纠结代码风格和其他优化。使用react 伪代码编写,仅为表达作者思路。
我们从最简单的操作开始
-
使用interface约束组件参数
例如我们需要在页面上显示一个用户信息,用户有两个字段分别是id和name,通常会这么写
import React from "react"; interface Props { user:{ id: string; name: string; } } const index = (props: Props) => { const user = props.user; return ( <div> id:{user.id}--name:{user.name} </div> ); }; export default index;
其中有一个小细节,关于interface User的声明位置,应该放到本组件内,还是单独提取出来呢?我更倾向于单独提取出来,可以放到src/interface文件夹或者符合你的项目规则的目录下,总之interface和组件不应该写到一个文件内,除非你真的只在这个组件内使用。我这里将interface放到src/user.ts中
user.ts
export interface User { id: string; name: string; }
然后在组件内引用此interface
import React from "react"; import User from "@/interface/user"; interface Props { user:User } const index = (props: Props) => { const user = props.user; return ( <div> id:{user.id}--name:{user.name} </div> ); }; export default index;
-
显示用户列表
这里我们不满足于仅仅显示一个用户信息,我们要显示用户列表时应该怎么使用interface呢,首先创建一个文件,引入对应的interface(这个时候你就知道为什么要将interface声明单独提取出来了)和组件Item(用于显示用户信息),声明用户列表变量用于渲染
list.tsx
import React,{useState,useEffect} from "react"; import User from "@/interface/user"; import Item from "./item"; const index = () => { const [userList,setUserList] = useState<Array<User>>([]); const initData = ()=> { //伪代码... let arr = []; for(let i = 0;i<10;i++){ let item = {id:i,name:"张三" + i}; arr.push(item); } return arr; } useEffect(()=>{ let arr = initData(); setUserList(arr); },[]); return ( <div> <p>列表</p> {userList.map(user=>{ //user就不用显示声明类型,TS会自动推导user是符合User Interface的 return <item user={user} />; }) } </div> ); }; export default index;
这里解释一下*useState<Array>,*意思是创建的对象是由符合User Interface对象的项组合成的数组。
-
调用服务端API
如何在调用服务端API时使用interface呢?我们举个例子,例如我们要获取用户列表,调用的API地址是/api/userList,这个API接收3个参数,分别是pageNumber(页码)、pageSize(每页条数)、status(状态),首先创建一个符合参数的interface
export interface UserListParams{ pageNumber:number; pageSize:number; status:number; }
那么这个interface应该放到哪里呢?我是放到了interface/user.ts文件内,另外也要考虑一个问题,像pageNumber和pageSize这种公共属性我们可以将它提取出来,做一个继承操作,具体做法参考如下,在interface文件夹内创建文件base.ts
export interface Page{ pageNumber:number; pageSize:number; }
继承
import type { Page } from "@/interface/base"; export interface UserListParams extends Page{ status:number; }
这样的话,其他的分页查询都可以通过继承Page来实现,当然这只是举个例子,如果你有其他的必要公共属性,也可以这么操作以优化你的代码。
接下来在调用API时引入这个interface以约束函数的参数,例如
import type { UserListParams } from "@/interface/user"; export getUserList = (userListParams:UserListParams) =>{request("/api/userList",userListParams)}
定义好请求方法后,在业务层调用即可,如下
import React,{useState,useEffect} from "react"; import Item from "./item"; import type { UserListParams, User } from "@/interface/user"; import { getUserList } from "@/api/user"; const index = () => { const [userList,setUserList] = useState<Array<User>>([]); const [userListParams,setUserListParams] = useState<UserListParams>({ pageNumer:1, pageSize:10, status:0 }); useEffect(()=>{ const res = await getUserList(userListParams); },[userListParams]); return ( <div> <p>列表</p> {userList.map(user=>{ //user就不用显示声明类型,TS会自动推导user是符合User Interface的 return <item user={user} />; }) } </div> ); }; export default index;
总结
哎,打工人好辛苦,蚌埠住了
转载自:https://juejin.cn/post/7006604966475350047