TypeScript泛型与其他补充类型

一、类的使用

1、implements 子句

  • 类可以实现接口,使用关键字 implements
  • 可以使用一个 implements 子句来检查一个类,是否满足了一个特定的接口。如果一个类不能正确地实现它,就会发出一个错误

注意点:

实现一个带有可选属性的接口并不能创建该属性

只要一个接口继承了某个类,那么就会继承这个类中所有的属性和方法,但是只会继承属性和方法的声明,不会继承属性和方法实现

与 extends 的区别:

extends:继承某个类,继承之后可以使用父类的方法,也可以重写父类的方法

implements:继承某个类,必须重写才可以使用

export default {}

interface IPersonInfo{
    name:string
    age:number
    sex?:string
    show():void
}
interface IMusic{
    music:string
}

class Person implements IPersonInfo,IMusic{
    name: string='吴谨言'
    age:number=21
    // sex:string='女'
    music:string='雪落下的声音'
    show(){
        console.log(`我叫${this.name},是主演延禧攻略的主演,今年${this.age}岁了`);
    }
}
let p = new Person()
p.show()
// p.sex='女';//报错

// 注意点:只要一个接口继承了某个类,那么就会继承这个类中所有的属性和方法
// 但是只会继承属性和方法的声明,不会继承属性和方法实现

interface ITest extends Person{
    salary:number
}

class Star extends Person implements ITest{
    name: string='关晓彤'
    age:number=20
    salary:number=100000
}

let s = new Star()
console.log(s.name);
console.log(s.salary);

二、泛型

1、泛型的基本使用

  • 泛型可以理解为宽泛的类型,通常用于类和函数。使用的时候我们再指定类型
  • ·泛型不仅可以让我们的代码变得更加健壮,还能让我们的代码在变得健壮的同时保持灵活性和可重用性
  • 通过用 <T> 来表示,放在参数的前面
export default {}

const arr1:string[]=['李易峰','陈伟霆','杨幂'];
const arr2:Array<string>=['成毅','杨紫']
const arr3:Array<number>=[12,63,23,48]

// 不使用泛型
let getArray = (value:number,item:number):number[]=>{
    return new Array(item).fill(value)
}
let arr = getArray(10,3)
// let arr = getArray('zhang',3);//报错
console.log(arr);

let getArray1 = (value:any,item:number):any[]=>{
    return new Array(item).fill(value)
}
console.log(getArray1(10,3));
console.log(getArray1('白鹿',3));

// 使用泛型
let getArray2 = <T>(value:T,item:number):T[]=>{
    return new Array(item).fill(value)
}
let res = getArray2<string>('鞠婧祎',2)
let res1 = getArray2<number>(2,2)
console.log(res);
console.log(res1);

2、泛型约束

  • 在TS中,我们需要严格的设置各种类型,我们使用泛型之后,将会变得更加灵活,但同时也将会存在一些问题
  • 我们需要对泛型进行约束来解决这些问题
export default {}

// 演示可能出现的问题
// function getLength<T>(arr:T):T{
//     console.log(arr.length);
//     return arr
// }

// 通用方法
function getLength<T>(arr:Array<T>):Array<T>{
    console.log(arr.length);
    return arr
}
getLength([1,2,3])
getLength(['赵丽颖','迪丽热巴','杨幂'])
// getLength('刘亦菲');//报错

// 泛型接口
interface ILength{
    length:number
}
function getLengths<T extends ILength>(arr:T):number{
    return arr.length
}
getLengths([1,2,3])
getLengths(['赵丽颖','迪丽热巴','杨幂'])
getLengths('刘亦菲')

3、泛型接口

  • 将泛型与接口结合起来使用,可以大大简化我们的代码,增加我们的代码可读性
  • 泛型也可以使用默认值
export default {}

interface IPerson{
    name:string
    sex:string
}
let p:IPerson={
    name:'李易峰',
    sex:'男'
}

interface IPersons<T1,T2>{
    name:T1
    sex:T2
}
let ps:IPersons<string,number>={
    name:'杨幂',
    sex:0
}

interface IPersos<T1=string,T2=string>{
    name:T1
    sex:T2
}
let pi:IPersos={
    name:'蔡徐坤',
    sex:'男'
}

4、泛型类

  • 泛型类看上去与泛型接口差不多。泛型类使用(<>)括起泛型类型,跟在类名后面。
export default {}

// 泛型类使用<>括起泛型类型,跟在类名后面
class Person<T1,T2>{
    name:T1
    age:T2
    sex:T1
    constructor(name:T1,age:T2,sex:T1){
        this.name=name
        this.age=age
        this.sex=sex
    }
}
const p1 = new Person('白鹿',18,'女')
const p2 = new Person<string,number>('迪丽热巴',18,'女')
const p3:Person<string,number>=new Person('白鹿',18,'女')

三、其他补充类型

1、unknown类型

  • unknown类型代表任何值。这与any类型类似,但更安全,因为对未知unknown值做任何事情都是不合法的。
  • unknown类型被称作安全的any
export default {}
//任何类型都可以赋值给unknown类型
let str: unknown
str = '李四'
str = 18
str = true

//不能将unknown类型赋值给其他类型
let val: unknown = 18
let num: unknown

//num=val
//类型断言
num = val as number

//类型缩小
if (typeof val == 'number') {
  num = val
}

//unknown与其他任何类型组成交叉类型最后i都是其他类型
type myType1 = number & number
type myType2 = unknown & boolean

let a:myType1=18;
let b:myType2 = false;

//unknown除了与any以外与其他任何类型组成的联合类型最后都是unknown类型
type myType3 = unknown | any
type myType4 = unknown | string
type myType5 = unknown | string | boolean

//never类型都是unknown类型的子类型
type myType6 = never extends unknown?true:false

2、Map类型

可以使用for of进行迭代

创建Map:

let myMap = new Map();

Map相关的函数与属性:

  • map.clear() 移除 Map对象的所有键/值对。
  • map.set() 设置键值对,返回该Map对象。
  • map.get() 返回键对应的值,如果不存在,则返回undefined。
  • map.has() 返回一个布尔值,用于判断 Map中是否包含键对应的值。
  • map.delete() 删除Map中的元素,删除成功返回true,失败返回false。
  • map.size() 返回Map 对象键/值对的数量。
  • map.keys() 返回一个Iterator对象,包含了Map对象中每个元素的键。
  • map.values() 返回一个新的lterator对象,包含了Map对象中每个元素的值。
export default{}

let nameMap = new Map()
//格式Map对象
nameMap.set("赵四",1)
nameMap.set("张三",1)
nameMap.set("六四",1)

//获取键对应的值
// console.log(nameMap.get("张三"));

//判断Map中是否包含键对应的值
console.log(nameMap.has("赵四"));
console.log(nameMap.has("六三"));

//返回Map对象键/值对的数量
console.log(nameMap.size);

//删除
console.log(nameMap.delete("赵四"));
console.log(nameMap.delete("六三"));

//移除Map对象的所有键/值对
nameMap.clear()
console.log(nameMap);

//迭代Map中的key
for(let key of nameMap.keys()){
    console.log(key);  
}

//迭代Map中的value
for(let value of nameMap.values()){
    console.log(value);  
}

//迭代Map中的key +> value
for(let entry of nameMap.entries()){
    console.log(entry[0],entry[1]);
}

//使用对象解析
for(let [key,value] of nameMap){
    console.log(key,value);
}

3、条件类型

  • 条件类型的形式看起来有点像JavaScript中的条件表达式
  • T extends U ? TrueType : FalseType
  • 应用场景:解决函数重载问题
export default {}

// 复习三元运算符  x=y?a:b
// let score = 30
// if(score>=60){
//     console.log("不及格");
// }else{
//     console.log("及格");
// }
// score>=60?"及格":"不及格"
let result=''
result=score>=60?'及格':'不及格'
console.log(result);


// 条件类型
type MyType<T>=T extends string ? string :any;
type res = MyType<string>


interface IName{
    name:string
}
interface IAge{
    age:number
}
type Condition<T>=T extends string ? IName :IAge;

function reLoad<T extends number | string>(idOrName:T):Condition<T>{
    throw "";
}
reLoad(19)
reLoad('zhang')

4、映射类型

  • 当你不想重复定义类型,一个类型可以以另一个类型为基础创建新类型。通俗的说就是,以一个类型为基础,根据它推断出新的类型
  • Readonly : Partial关键字
  • Record : Pick 映射类型
  • Readonly,Partial和Pick是同态的,但Record不是。因为Record并不需要输入类型来拷贝属性,所以它不属于同态
export default{}
//Record映射类型
//他就将一个类型的所有属性值都映射到另一个类型上并创造一个新的类型
type Name="person"|"animal"
type Person={
    name:string
    age:number
}
type NewType=Record<Name,Person>
let res:NewType={
    person:{
        name:"富兰克林",
        age:18
    },
    animal:{
        name:"小查",
        age:3,
    }
}
console.log(res);

 //Pick映射类型
 //将原来的类型中的vud内容映射到新类型中
interface IPerson{
    name:string
    age:number
}
type MyType = Pick<IPerson,"name">
let res2:MyType={
    name:"催付"
}
console.log(res2);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值