高级用法

泛型定义

泛型(Generics)是只在定义函数,接口或类的时候,不预先指定具体的类型,而在使用的时候再指定类型的一种特征

泛型 T 作用于只限在函数的内部

必须要把val指定为any类型,可以传入任意类型,但是不够灵活
val不是所有类型都可以,所以需要使用泛型

1
2
3
4
5
6
7
8
9
10
function  createArray(length:number,val:any):Array<any> {
let result:Array<any> =[];
for(let i=0;i<length;i++){
result.push(val);
}
return result;
}

let result = createArray(3,"x");
console.log(result);

期望的是val的什么类型,最终返回的就是这个类型的数组

1
2
3
4
5
6
7
8
9
10
function  createArray<T>(length:number,val:T):Array<T> {
let result:Array<T> =[];
for(let i=0;i<length;i++){
result.push(val);
}
return result;
}
// 在是用的时候传入声明的类型
let result = createArray<string>(3,"x");
console.log(result);

接口泛型

因为T是未知类型,所以返回值中不能经行运算

1
2
3
4
5
6
7
8
9
interface M {
<T>(a:T,b:number):T
}

const fn:M = function <T>(a:T,b:number) {
return a;
}

fn("1",1);

多类型参数

1
2
3
4
5
const swap = function swap<A,B>(arr:[A,B]):[B,A] {
return [arr[1],arr[0]];
}

console.log(swap<string,number>(['a',2]))

默认泛型

1
2
3
4
5
const swap = function swap<A,B=number>(arr:[A,B]):[B,A] {
return [arr[1],arr[0]];
}

console.log(swap<string>(['a',2]))

泛型约束

在函数中使用泛型的时候,由于预先不知道具体使用的类型,所以不能访问相应类型的方法

1
2
3
4
function logger<T>(val:T):number {
// 报错: 不能确定val的类型,所以不能检查
return val.length;
}
1
2
3
4
5
6
7
interface Logger {
length:number
}

function logger<T extends Logger>(val:T):number {
return val.length;
}

泛型类型别名

interface定义一个真实的接口,是一个真正的类型

type 一般用来定义别名,并不是一个真正的类型

1
2
3
4
5
6
7
8
9
interface Cart<T> {
list:T[]
}

// 泛型类型别名
type Cart2<T> ={list:T[]}|T[];

const c1:Cart2<string> = ['1']
const c2:Cart2<string> = {list:['1']}

交叉类型

1
2
3
4
5
6
7
8
9
interface Bird{
fly():void
}

interface Boy{
name:string
}

type BirdBoy = Bird & Boy

typeof 获取类型

1
2
3
4
5
6
7
8
const boy  = {
name:'1'
}
type Boy = typeof boy;

const p:Boy ={
name:"123"
}

索引访问

1
2
3
4
5
6
7
8
interface Boy{
name:string,
info:{
id:number
}
}

const boy:Boy['info']['id'] = 123

索引类型查询操作符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const boy:Boy = {
name:"boy",
id:1,
info:{
aaa:123
}
}

type PropType = keyof Boy;

function getData(target:Boy,prop:PropType) {
return target[prop];
}

getData(boy,'info')

映射类型

部分属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
interface Boy{
name:string,
id:number,
info:{
aaa:number
}
}

// 部分属性
type PartialBoy = {
[k in keyof Boy]?:Boy[k]
}

const boy:PartialBoy = {
name:'123'
}

原生提供的方法及实现

1
2
3
4
5
6
7
8
9
10
11
// Partial 实现
type Partial<T> ={
[key in keyof T]?:T[key]
}

// 原生方法
type PartialBoy = Partial<Boy>;

const boy:PartialBoy = {
name: "name"
}

所有属性必须有

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// Required 实现
type Required<T> ={
[key in keyof T]-?:T[key]
}

// 原生方法
type PartialBoy = Required<Boy>;

const boy:PartialBoy = {
name: "name",
id:123,
info:{
aaa:111
}
}

属性只读

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// Readonly 实现
type Readonly<T> ={
readonly [key in keyof T]:T[key]
}

// 原生方法
type PartialBoy = Readonly<Boy>;

const boy:PartialBoy = {
name: "name",
id:123,
info:{
aaa:111
}
}

// 报错
boy.name = 1;

pick 指定属性

1
2
3
4
5
6
7
8
9
10
11
12
13
// Pick 实现
// 只能摘取某一项返回
type Pick<T,K extends keyof T> ={
[key in K]:T[key]
}

// 原生方法
type PartialBoy = Pick<Boy,'id'>;

const boy:PartialBoy = {
id:123,
name:'123' // 报错
}

条件类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
interface Bird {
name1:string
}

interface Fish {
name2:string
}

interface Water {
name3:string
}

interface Sky {
name4:string
}

type Combin<T> = T extends Bird ? Sky : Water;

const ins:Combin<Fish | Bird> = {
name4: '123',
name3:'123'
}
打赏
  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!
  • Copyrights © 2015-2025 SunZhiqi

此时无声胜有声!

支付宝
微信