目录
implements字句
泛型基本使用
泛型约束
泛型接口
泛型类
补充类型
unknown类型
map对象
条件类型
映射类型
类可以实现接口,使用笑键字implements
可以使用一个implements子句来检查一个类,是否满足了一个特定的接口。如果一个类不能正确地实现它,就会发出一个错误
注意点:
实现一个带有可选属性的接口并不能创建该属性
只要一个接口继承了某个类.那么就会继承这个类中所有的属性和方法,但是只会继承属性和方法的声明,不会继承属性和方法实现
与extends的区别
extends:继承某个类,继承之后可以使用父类的方法,也可以重写父类的方法
implements:继承某个类,必须重写才可以使用
interface IPerson{
name:string
age:number
sex?:string
show():void
}
interface Imusic{
music:string
}
class Person implements IPerson,Imusic{
name: string='许嵩'
age:number=20
sex:string='男'
music:string='庐州月'
show(){
console.log(`我是${this.name},今年${this.age}岁了,我唱过${this.music}`);
}
}
let a = new Person()
a.show()
interface Ipon extends Person{
aaa:string
}
class IPon extends Person implements IPon{
aaa: string='周杰伦'
}
let b = new IPon()
console.log(b.aaa);
泛型可以理解为宽泛的类型,通常用于类和函数。使用的时候我们再指定类型
泛型不仅可以让我们的代码变得更加健壮,还能让我们的代码在变得健壮的同时保持灵活性和可重用性
通过用
let getArray = (value:T,items:number):T[]=>{
return new Array(items).fill(value)
}
let a = getArray('周杰伦',10)
console.log(a);
在TS中,我们需要严格的设置各种类型,我们使用泛型之后,将会变得更加灵活,但同时也将会存在一些问题我们需要对泛型进行约束来解决这些问题
interface Iaa{
length:number
}
function aa(arr:T):number{
return arr.length
}
aa('大家撒')
aa([1,2,5,8,9,6,3])
let p = aa(['请求','王五'])
console.log(p);
将泛型与接口结合起来使用,可以大大简化我们的代码,增加我们的代码可读性。
泛型也可以使用默认值
interface IPerson{
name:T1
age:T2
}
let p:IPerson={
name:'王五',
age:20
}
console.log(p);
泛型类看上去与泛型接口差不多。泛型类使用()括起泛型类型,跟在类名后面。
class Person{
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('周杰伦',20,'男')
console.log(p);
let p1 = new Person('许嵩',20,'男')
console.log(p1);
let p2:Person = new Person('林俊杰',20,'男')
console.log(p2);
unknown类型代表任何值。这与any类型类似,但更安全,因为对未知unknown值做任何事情都是不合法的。unknown类型被称作安全的any
任何类型都可以赋值给unknown类型
let str:unknown
str = 18
str = '王五'
str = true
不能将unknown类型赋值给其他类型
let val:unknown = 18;
let num:number;
// num=val; //报错
适用类型断言
num = val as number
使用类型缩小
if(typeof val == 'number'){
num == val
}
unknown与其他任何类型组成的交叉类型最后都是其他类型
type MyType = number & unknown
type MyType2 = unknown & boolean
let a:MyType = 18
let b:MyType2 = true
unknown除了与any以外,与其他任何类型组成的联合类型最后都是unknown类型
type MyType3 = unknown | any
type MyType4 = unknown | number
type MyType5 = unknown | string | boolean
never类型是unknown类型的子类型
type MyType6 = never extends unknown ? true:false
Map对象保存键值对,并且能够记住键的原始插入顺序。
任何值(对象或者原始值)都可以作为一个键或一个值。
Map 是ES6中引入的一种新的数据结构
可以使用for of进行迭代
Map相关的函数与属性:
map.clear()-移除Map对象的所有键/值对。
map.set()-设置键值对,返回该Map对象。
map.get()-返回键对应的值,如果不存在,则返回undefined。
map.has()-返回一个布尔值,用于判断Map中是否包含键对应的值。
map.delete()–删除Map中的元素,删除成功返回true,失败返回false。
map.size -返回Map对象键/值对的数量。
map.keys()-返回一个lterator对象,包含了Map对象中每个元素的键。
map.values()-返回一个新的Ilterator对象,包含了Map对象中每个元素的值。
// 创建map对象
let aa = new Map();
// 设置map对象
aa.set("周杰伦",1)
aa.set("许嵩",1)
aa.set("林俊杰",1)
// 获取map对象的值
console.log(aa.get('许嵩'));
// 清空map对象
// aa.clear()
// console.log(aa);
// 判断map对象中是否包含键对应的值 返回true或false
console.log(aa.has('许嵩'));
// 删除map对象中的元素 返回true或false
console.log(aa.delete('许嵩'));
// 返回map对象键/值的数量
console.log(aa.size);
// 循环map对象中的键
for(let a of aa.keys()){
console.log(a);
}
// 循环map对象中的值
for(let a of aa.values()){
console.log(a);
}
// 对象解析
for(let [a,b] of aa){
console.log(a,b);
}
条件类型的形式看起来有点像JavaScript中的条件表达式
T extends U ? TrueType : FalseType
应用场景:解决函数重载问题
条件类型
interface Ia{
name:string
}
interface Ib{
age:number
}
type c=T extends string?string:any
type res = c
应用场景 解决函数重载问题
type Cond = T extends string?Ia:Ib
function reLoad(idOr:T):Cond{
throw ""
}
let res1 = reLoad('王世鑫')
let res2 = reLoad(20)
Record 映射类型
它会将一个类型的所有属性值都映射到另一个类型上并创造ige新的类型
type Name ="person"|"animal"
type Person={
name:string
age:number
}
type NewType=Record
let res :NewType ={
person:{
name:"克兰",
age:18
},
animal:{
name:"小小",
age:3
}
}
console.log(res);