泛型
面向对象编程的经典概念
泛型是指广泛的类型,类型也支持像函数一样的参数
type A = "hi" | 123 //TS
var a = ["hi", 123] //JS
type F<T> = T | T[]
type FNumber = F<number>
type FString = F<string>
var fn = (x: number) => x + 1
//泛型 = 广泛的类型
type Add<T> = (a: T, b: T) => T //这个T代表任何类型
// type AddNumber = Add<number>
// type AddString = Add<string>
const addN: Add<number> = (a, b) => a + b
const addS: Add<string> = (a, b) => a + ' ' + b
泛型的实际应用
import React, {FunctionComponent} from 'react';
type P = {
name: string
}
const App: FunctionComponent<P> =(props)=>{
props
return <div>hi</div>
}
props只有两个属性,一个是name,一个是children,children是右边ReactNode的属性,name是P的属性,他们俩加起来就得到props的属性
泛型一般情况下不会只有一层,它会存在多层,泛型里面传泛型,函数能干什么,泛型就能干什么,几乎在形式上一模一样
代入法:在泛型的应用中,我们不知道属性的时候,试着用代入法,代入到最后就知道了属性。
重载
type Add<T> = (a: T, b: T) => T
const add: Add<number | string> = (a, b) => {
return 'hi'
}
add('hi','Lily') //可以这样写
add(1, 2) //就要这样写
add('hi', 1) //存在bug
//在泛型中,如果参数同时有number或string,那么属性中无法区别哪一个是string,哪一个是number
//重载中喊多种参数
type Options = { header?: any }
function get(url: string, options?: Options): void
function get(options: Options & {url:string}): void
function get(url: string | (Options & {url:string}), options?: Options): void{
if(arguments.length === 1){
const myOptions = url as {url: string} & Options
myOptions.url
}else{
console.log((url as string))
}
}
//重载
function add2(a: number, b: number): number;
function add2(a: string, b: string): string;
function add2(a: any, b:any): any{
if (typeof a === 'number' && typeof b === 'number'){
return a + b
}else{
return a + ' ' + b
}
}
add2(1, 2) //number
add2('hi', 'lily') //string
export {}
在重载中,如果写add2(1, 'hi'),会出现下面的错误 :
第 1 个重载(共 2 个),“(a: number, b: number): number”,出现以下错误。
类型“string”的参数不能赋给类型“number”的参数。
第 2 个重载(共 2 个),“(a: string, b: string): string”,出现以下错误。
类型“number”的参数不能赋给类型“string”的参数。
重载是为了让函数满足多种的参数条件,一种是用typeof来判断,一种是用arguments.length(参数的长度)来判断
如何用泛型封装网络请求库
type User = {
id: string | number;
name: string;
age: number;
}
type Response<T> = {
data: T
}
type T = Omit<Partial<User>, 'id'>
//还可以写成
//type T = Partial<Omit<User, 'id'>>
type CreateResource = (path: string)=>{
create: (attrs: Omit<Partial<User>, 'id'>)=> Promise<Response<User>>
delete: (id: User['id']) => Promise<Response<never>>
update: (id: User['id'], attrs: Omit<Partial<User>, 'id'>) => Promise<Response<User>>
get: (id: User['id']) => Promise<Response<User>>
getPage: (page: number) => Promise<Response<User[]>>
}
const createResource = (path: string) =>{
return {
create(attrs){
const url = path + 's'
return axios.post<User>(url, {data:attrs})
},
delete(){},
update(){},
get(){},
getPage(){}
}
}
var userResource = createResource('/api/v1/user')
//(attrs: Omit<Partial<User>, 'id'>)是指可以穿User的所有属性,这些属性中唯独忽略掉其中的id属性
进行增删改查