ts中的类、接口、泛型
1、定义类,static关键字,readonly
定义类:
//通过class这个关键字来定义一个类 class Persion{ name:string; age:number; } //通过这个类实例化一个对象 let man=new Persion();
静态修饰符(static),修饰属性或方法,属于类,只能通过类名调用
class Person{ static name:string='xdclass'; static sayHello(){ console.log("嗨!!!!"); }; } Person.sayHello(); Person.name
readonly修饰的属性,只能读取不能修改
class Person { readonly name: string age: number constructor(name: string, age: number) { this.name = name this.age = age } } const person = new Person("fa",123); person.name = "3234" //报错
2、构造方法
用constructor声明构造方法
class Person { readonly name: string age: number constructor(name: string, age: number) { this.name = name this.age = age } }
3、继承、重写、super关键字
继承用extends关键字,跟java用法一样。
重写指的是子类重写父类的属性或方法,跟java用法一样。
super关键字,在子类中调用父类的构造方法用,跟java一样。
4、抽象类
用abstract关键字定义的类,跟java一样。
abstract class Dog { name: string abstract bulk(): void eat(): void { console.log("吃骨头") } }
5、接口(重要)
有三点:
(1)接口可以做类型声明
// 之前学过的类型别名 type myType=string|number; let a:myType; a=123; a=true; //报错 // 接口可以做类型声明 interface myInterface{ //名称一样的接口属性取并集 name:string; sleep():void; } interface myInterface{ //名称一样的接口属性取并集 age:number; } let b:myInterface; //类型声明 b={ name:'xdclass', age:12, sleep(){ console.log("myInterface"); } } console.log(b.name); //xdclass b.sleep(); //myInterface
(2)同名接口,属性取并集,看上面的代码例子
(3)类可以实现接口
interface myInterface { //名称一样的接口属性取并集
name: string;
sleep(): void;
}
interface myInterface { //名称一样的接口属性取并集
age: number;
}
class Person implements myInterface {
name: string;
age: number;
gender: string;
sleep() {
console.log(this.name);
}
constructor(name: string, age: number, gender: string) {
this.name = name;
this.age = age;
this.gender = gender;
}
}
let c = new Person('小D', 12, '男');
console.log(c);
c.sleep();
6、成员修饰符
(1)属性修饰符
public:修饰的属性可以在任意位置访问(修改),是默认值
private: 私有属性,私有属性只能在类内部访问(修改)
protected: 受保护的属性,只能在当前类和当前类的子类中访问(修改)
(2)属性封装
就是使用private修饰
(3)属性存取器
getter 读取属性
setter 设置属性
-使用场景,设置和读取属性的时候,可以加一些限制
class Person{ name:string; private age:number; constructor(name:string,age:number){ this.name=name; this.age=age; }; get getAge(){ return this.age; }; set setAge(age:number){ if(age>=0){ this.age=age; } } } let obj =new Person("老帆",26); obj.setAge=12; obj.setAge=-12; //不能设置成功 console.log(obj.getAge);
7、泛型(重要)
为什么要有泛型?比如有个需求,把传入的参数返回去,如果使用any,则会关闭ts的类型检测。不仅影响自己,还会在赋值时关闭其他变量的类型检测
//需求: 定义一个函数 把传入的参数返回出去 function cache(prop:string):string{ return prop; } // any, 不行,使用any会关闭ts的类型检测 function cache(prop:any):any{ return prop; } // 泛型,ok function cache<T,P>(prop:T,flag:P):T{ return prop; } let a=cache<string,number>("true",1223);
(1)泛型使用场景
在定义函数或类时,如果遇到类型不明确就可以使用泛型——泛型就是一个不确定的类型
(2)如何使用简单的泛型

(3)泛型的约束
指的是在使用的时候,指定类型。上面的 let a=cache<string,number>("true",1223); 就是指定了泛型约束
如果我们不指定,TS解析器会根据我们传递的参数进行类型推测(建议在使用泛型的时候指定泛型的类型)
(4)创建多个泛型

(5)泛型在接口中的使用
interface myInterface<T>{ name:T; } class Person<T,P> implements myInterface<T>{ name:T; age:P; constructor(name:T,age:P){ this.name=name; this.age=age; } } let obj=new Person<string,number>("老帆",30); console.log(obj); //Person { name: '老帆', age: 30 }
8、泛型高级用法之keyof(重要)
先看下面的代码
interface Person { name: string age: number gender: string } class Teacher { constructor(public info: Person) { } getInfo(key: string) { return this.info[key] } } const teacher = new Teacher({ name: 'lee', age: 22, gender: 'male' }) console.log(teacher.getInfo('name1'));
//以上代码的问题:getInfo的返回值类型,不能根据我传的key动态变化,而永远是 string|number|undefined
//我要实现的效果是:我传"name"或"gender"getInfo方法返回值类型为string,传"age"返回值类型为number
interface Person { name: string age: number gender: string } class Teacher { constructor(public info: Person) { } getInfo<T extends keyof Person>(key: T): Person[T] { return this.info[key] } } const teacher = new Teacher({ name: 'lee', age: 22, gender: 'male' }) console.log(teacher.getInfo('gender'));
浙公网安备 33010602011771号