浅谈interface 与 type的区别
1.interface 与 type都能用来描述对象和函数的类型
name: string,
age: number,
say(s:string,y:string): string,
};
interface People {
name: string,
age:number,
say(x:string,y:string):string
}
let testObj:User = {
name: '李四',
age: 23,
say(x,y){ return x + y}
}
console.log(testObj.say('你','我'));
2.interface 和 type都能进行类型扩展
不过需要注意的是
interface用的是extends, 而type用的是 & 符号
name: string;
}
interface User extends Name {
age: number
}
let stu:User = {name: 'wang', age: 10}
//interface的扩展可以通过type交叉(&)类型实现
type Name = {
name: string;
}
type User = Name & {age: number}
let stu:User={name: 'wang', age: 18}
//interface 扩展 type
type Name = {
name: string;
}
interface User extends Name {
age: number;
}
let stu:User={name: 'wang', age: 89}
//type与interface交叉
interface Name {
name: string;
}
type User = Name & {
age: number;
}
let stu:User={name:'wang', age: 18}
3.类型名定义相同时,interface 会合并而 type 会报错
interface Name {
name: string
}
interface Name {
age: number
} // 正常运行切回合并
type Name = {
name: number
}
type Name = {
age: number
} // 报错
字面量与联合类型的使用
1.字面量类型
let str1 = 'abc'
const str2 = 'abc'
通过 TS 类型推论机制,可以得到答案:
- 变量 str1 的类型为:string
- 变量 str2 的类型为:'abc'
解释:
- str1 是一个变量(let),它的值可以是任意字符串,所以类型为:string
- str2 是一个常量(const),它的值不能变化只能是 'abc',所以,它的类型为:'abc'
注意:此处的 'abc',就是一个字面量类型,也就是说某个特定的字符串也可以作为 TS 中的类型,任意的 JS 字面量(比如,对象、数字等)都可以作为类型使用
2.字面量类型的实际应用
type Gender = '男' | '女'
let gender: Gender = '女'
3.联合类型
联合类型和交叉类型比较相似,联合类型通过|符号连接多个类型从而生成新的类型。它主要是取多个类型的交集,即多个类型共有的类型才是联合类型最终的类型。联合类型可以是多个类型其中一个,可做选择,比如:string | number,它的取值可以是string类型也可以是number类型。
3.1 声明变量的时候设置变量类型
let a:string|number|boolean;
a = 's';
a = 1;
a= false;
3.2 多个接口类型进行联合
interface X{
q:number,
w:string,
r:string
}
interface Y{
q:number
r:string,
}
type XY = X | Y
let value:XY = {
q:1,
r:'r'
}
3.3 函数接口类型联合
interface X{
x:()=>string;
y:()=>Number;
}
interface Y{
x:()=>string;
}
type XY = X|Y;
function func1():XY{
//此处不进行类型断言为XY在编辑器中会报类型错误
return {} as XY
}
let testFunc = func1();
testFunc.x();
testFunc.y(); //Error:类型“XY”上不存在属性“y”,类型“Y”上不存在属性“y”。
axios 在 TypeScript 的使用
import axios from 'axios'
import type { AxiosInstance, AxiosRequestConfig, AxiosResponse, InternalAxiosRequestConfig } from 'axios'
// 定义一个常见后端请求返回
type BaseApiResponse<T> = {
code: number
message: string
result: T
}
// 拓展 axios 请求配置,加入我们自己的配置
interface RequestOptions {
// 是否全局展示请求 错误信息
globalErrorMessage?: boolean
// 是否全局展示请求 成功信息
globalSuccessMessage?: boolean
}
// 拓展自定义请求配置
interface ExpandAxiosRequestConfig<D = any> extends AxiosRequestConfig<D> {
interceptorHooks?: InterceptorHooks
requestOptions?: RequestOptions
}
// 拓展 axios 请求配置
interface ExpandInternalAxiosRequestConfig<D = any> extends InternalAxiosRequestConfig<D> {
interceptorHooks?: InterceptorHooks
requestOptions?: RequestOptions
}
// 拓展 axios 返回配置
interface ExpandAxiosResponse<T = any, D = any> extends AxiosResponse<T, D> {
config: ExpandInternalAxiosRequestConfig<D>
}
export interface InterceptorHooks {
requestInterceptor?: (config: InternalAxiosRequestConfig) => InternalAxiosRequestConfig
requestInterceptorCatch?: (error: any) => any
responseInterceptor?: (response: AxiosResponse) => AxiosResponse | Promise<AxiosResponse>
responseInterceptorCatch?: (error: any) => any
}
// 导出Request类,可以用来自定义传递配置来创建实例
export default class Request {
// axios 实例
private _instance: AxiosInstance
// 默认配置
private _defaultConfig: ExpandAxiosRequestConfig = {
baseURL: '/api',
timeout: 5000,
requestOptions: {
globalErrorMessage: true,
globalSuccessMessage: false
}
}
private _interceptorHooks?: InterceptorHooks
constructor(config: ExpandAxiosRequestConfig) {
// 使用axios.create创建axios实例
this._instance = axios.create(Object.assign(this._defaultConfig, config))
this._interceptorHooks = config.interceptorHooks
this.setupInterceptors()
}
// 通用拦截,在初始化时就进行注册和运行,对基础属性进行处理
private setupInterceptors() {
this._instance.interceptors.request.use(this._interceptorHooks?.requestInterceptor, this._interceptorHooks?.requestInterceptorCatch)
this._instance.interceptors.response.use(this._interceptorHooks?.responseInterceptor, this._interceptorHooks?.responseInterceptorCatch)
}
// 定义核心请求
public request(config: ExpandAxiosRequestConfig): Promise<AxiosResponse> {
// !!!⚠️ 注意:axios 已经将请求使用 promise 封装过了
// 这里直接返回,不需要我们再使用 promise 封装一层
return this._instance.request(config)
}
public get<T = any>(url: string, config?: ExpandAxiosRequestConfig): Promise<AxiosResponse<BaseApiResponse<T>>> {
return this._instance.get(url, config)
}
public post<T = any>(url: string, data?: any, config?: ExpandAxiosRequestConfig): Promise<T> {
return this._instance.post(url, data, config)
}
public put<T = any>(url: string, data?: any, config?: ExpandAxiosRequestConfig): Promise<T> {
return this._instance.put(url, data, config)
}
public delete<T = any>(url: string, config?: ExpandAxiosRequestConfig): Promise<T> {
return this._instance.delete(url, config)
}
}