TypeScript

implements字句

export default{}

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

interface IMusic{
    music:string
}

class Person implements IPersonInfo,IMusic{
    music: string="雪落下的时候"
    name: string="刘菲菲";
    age:number=18;
    sex:string="女";
    show(){
        console.log(`我是${this.name},年龄是${this.age}岁,我主演了电视剧`);
    }
}
let p =new Person();
p.show()

interface ITest extends Person{
    salary:number
}

class Star extends Person implements ITest{
    name:string="关晓彤";
    age:number=20;
    salary:number=10000000;
}
let s =new Star()
console.log(s.salary);
console.log(s.name);

1.泛型的基本使用

要解决上面这个场景的问题,就需要使用泛型了。泛型(Generics)是指在定义函数、接口或类的时候,不预先指定具体的类型,而在使用的时候再指定类型的一种特性。

还拿上面这个例子中的逻辑来举例,我们既要允许传入任意类型的值,又要正确指定返回值类型,就要使用泛型。我们先来看怎么改写:

const getArray = <T>(value: T, times: number = 5): T[] => {
  return new Array(times).fill(value);
};
 

我们在定义函数之前,使用<>符号定义了一个泛型变量 T,这个 T 在这次函数定义中就代表某一种类型,它可以是基础类型,也可以是联合类型等高级类型。定义了泛型变量之后,你在函数中任何需要指定类型的地方使用 T 都代表这一种类型。比如当我们传入 value 的类型为数值类型,那么返回的数组类型T[]就表示number[]。现在我们再来调用一下这个 getArray 函数:

getArray<number[]>([1, 2], 3).forEach(item => {
  console.log(item.length);
});
getArray<number>(2, 3).forEach(item => {
  console.log(item.length); // 类型“number”上不存在属性“length”
});
 

我们在调用 getArray 的时候,在方法名后面使用<>传入了我们的泛型变量 T 的类型number[],那么在定义 getArray 函数时使用 T 指定类型的地方,都会使用number[]指定。但是你也可以省略这个<number[]>,TypeScript 会根据你传入函数的 value 值的类型进行推断:

getArray(2, 3).forEach(item => {
  console.log(item.length); // 类型“number”上不存在属性“length”
});
 

2.泛型约束

当我们使用了泛型时,就意味着这个这个类型是任意类型。但在大多数情况下,我们的逻辑是对特定类型处理的。还记得我们前面讲泛型变量时举的那个例子——当访问一个泛型类型的参数的 length 属性时,会报错"类型“T”上不存在属性“length”",是因为并不是所有类型都有 length 属性。

所以我们在这里应该对 T 有要求,那就是类型为 T 的值应该包含 length 属性。说到这个需求,你应该能想到接口的使用,我们可以使用接口定义一个对象必须有哪些属性:

interface ValueWithLength {
  length: number;
}
const v: ValueWithLength = {}; // error Property 'length' is missing in type '{}' but required in type 'ValueWithLength'
 

泛型约束就是使用一个类型和extends对泛型进行约束,之前的例子就可以改为下面这样:

interface ValueWithLength {
  length: number;
}
const getLength = <T extends ValueWithLength>(param: T): number => {
  return param.length;
};
getLength("abc"); // 3
getLength([1, 2, 3]); // 3
getLength({ length: 3 }); // 3
getLength(123); // error 类型“123”的参数不能赋给类型“ValueWithLength”的参数
 

这个例子中,泛型变量T受到约束。它必须满足接口ValueWithLength,也就是不管它是什么类型,但必须有一个length属性,且类型为数值类型。例子中后面四次调用getLength方法,传入了不同的值,传入字符串"abc"、数组[1, 2, 3]和一个包含length属性的对象{ length: 3 }都是可以的,但是传入数值123不行,因为它没有length属性。

3.泛型接口

将泛型与接口结合起来使用,可以大大简化我们的代码,增加我们的代码可读性。

// 泛型也可以使用默认值

interface IPerson<T1=string,T2=number>{
    name:T1
    age:T2
  }
  let p:IPerson={
    name:'王五',
    age:20
  }
  console.log(p);

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
   }
}
let p =new Person<string,number>("刘亦菲",18,"女");
console.log(p);

1.unknown类型

export default{}

//2.不能将unknow类型赋值给其它类型
let val:unknown=18;
let num:number;
// num=val;//报错
// 使用类型断言
num= val as number;
//使用类型缩小
if(typeof val=="number"){
    num =val;
}
//3.unknown与其他任何类型组成的交叉类型最后都是其他类型
type MyType1 = number & unknown;
type MyType2 = unknown &boolean;
let a: MyType1 = 18;
let b: MyType2 = true;

//4.unknown 除了与any以外,与其他任何类型组成的联合类型最后都是unknown类型

type MyType3 = unknown | any;

type MyType4 = unknown | number;

type MyType5 = unknown | string | boolean;

//5.never 类型是unknown类型的子类型
type MyType6 = never extends unknown ? true :false;

2.map类型

export default{}
let nameSjteMapping= new Map();
//设置Map对象
nameSjteMapping.set("薛之谦",1)
nameSjteMapping.set("薛之",2)
nameSjteMapping.set("薛",3)

//获取键对应的值
console.log(nameSjteMapping.get("Runoob"));  //2

//判断Map中是否包含键对应的值
console.log(nameSjteMapping.has("Taobao"));  //true
console.log(nameSjteMapping.has("zhihu"));   //false

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

//删除Runppb
console.log(nameSjteMapping.delete("Runoob"));//ture
console.log(nameSjteMapping.delete("zhihu"));  //false

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

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

    
}

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





3.条件类型

export default{}

//复习三元运算符   xxx==yy?a:b
// let score=30;
// let res=""
// res = score>=60?"及格":"不及格"
// console.log(res);


interface  IName{
    name:string
}
interface IAge{
    age:number
}
//条件类型
type Condition<T>=T extends string? IName:IAge
function reload<T extends string | number>(idOrName:T):Condition<T>{
    throw "";

}
reload(18);
reload("赵丽颖");

4.映射类型

Record 映射类型

//它会将一个类型的所有属性值都映射到另一个类型上并创造ige新的类型]

export default{}
//Record 映射类型
//它会将一个类型的所有属性值都映射到另一个类型上并创造ige新的类型]
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);

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值