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 {}


// 1.任何类型都可以赋值给unknown类型
let str:unknown
str=18
str=true
str='范冰冰'

// 2.不能将unknown类型赋值给其他类型
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 = boolean | unknown;
type MyType6 = unknown | string | boolean;

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

2、Map类型

Map 对象保存键值对,并且能够记;住键的原始插入顺序。

任何值(对象或者原始值)都可以作为一个键或一个值。

Map 是ES6中引入的一种新的数据结构

可以使用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 {}

// 创建Map对象
let myMap = new Map()

// 设置Map对象
myMap.set('李易峰',1)
myMap.set('陈伟霆',2)
myMap.set('黄明昊',3)

// 获取键对应的值
console.log(myMap.get('李易峰'));//1
console.log(myMap.get('唐嫣'));//因为不存在,所以是undefined

// 判断Map中是否包含键对应的值
console.log(myMap.has('黄明昊'));//true
console.log(myMap.has('虞书欣'));//false

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

// 删除
// console.log(myMap.delete('李易峰'));//true
console.log(myMap.delete('李易峰11'));//false

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

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

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

// 迭代Map中的key => value
for(let entry of myMap.entries()){
    console.log(entry);
}

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

3、条件类型

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

// 复习三元运算符  x=y?a:b
let score=56
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('bobo')

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:15
    }
}
console.log(res);

// Pick映射类型
// 将原有类型中的部分内容映射到新类型中
interface IPerson{
    name:string
    age:number
}
type MyType = Pick<IPerson,'name'>;
let res1:MyType={
    name:'韩雪'
}
console.log(res1);
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
TypeScript中,是一种用于创建可以多种类型上工作的可重用代码的技术。使用可以增强代码的灵活性和类型安全性。 要使用,可以在函数、类或接口的定义中使用尖括号(<>)来指定参数。例如,以下是一个使用的简单示例: ```typescript function identity<T>(arg: T): T { return arg; } let result = identity<number>(5); console.log(result); // 输出:5 ``` 在上面的例子中,`identity`函数使用了一个参数`T`,它表示函数的参数和返回值的类型是一致的。我们在调用`identity`函数时,显式指定了参数为`number`,因此返回值的类型为`number`。 另外,还可以使用约束来限制参数的类型。例如,如果希望参数必须具有某种特定属性,可以使用约束来实现: ```typescript interface HasLength { length: number; } function printLength<T extends HasLength>(arg: T): void { console.log(arg.length); } printLength("Hello"); // 输出:5 printLength([1, 2, 3]); // 输出:3 printLength({ length: 10 }); // 输出:10 ``` 在上述示例中,`printLength`函数使用了一个约束`T extends HasLength`,它表示参数`T`必须具有`length`属性。因此,我们可以传递包含`length`属性的字符串、数组或对象作为参数,函数会打印出其长度。 通过使用,我们可以编写更加通用和灵活的代码,可以在多种类型上进行操作而不需要重复编写逻辑。同时,TypeScript类型检查器也能够在编译时检测出类型错误,提供更高的类型安全性。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值