接口是对类的一部分行为的抽象
类类型
实现接口
为什么不是描述类呢?而是类一部分行为的抽象?
类中分为:静态部分(构造器)、实例部分(类成员)。
- 类成员:实例的属性、原型上的方法。
- 接口就是为了修饰类成员。
- 静态部分:constructor
- 构造函数是不能通过接口实现的,接口实现的是构造函数实例化的对象。
类的本质是构造函数,构造函数上没有类成员,所以接口不能描述类,而是说类实现的这个接口。
类实现的这个接口:接口描述属性,在类中去具体实现。
接口描述了类的公共部分
总结:修饰类需要写两个接口 + 一个函数:一个接口用来修饰类成员,一个接口用来修饰类构造函数本身,用一个函数把两者合并。
interface IPerson {
name: string;
sayName: (a: string) => void;
}
interface IPersonCons {
new (a: string): IPerson;
hobby: string;
sayHobby: (b: string) => void;
}
class Person implements IPerson {
name ='123';
sayName(c: string) {
console.log(this.name, c);
}
constructor(a:string) {
this.name = a;
};
static hobby = '123';
static sayHobby (b: string){
console.log(this.hobby, b);
}
}
function createPerson(c:IPersonCons): IPerson{
return new c('zhangsan');
}
let person = createPerson(Person);
console.log(person.name); //zhangsan
person.sayName('white'); //zhangsan white
person.sayName('white'); //zhangsan white
console.log(Person.hobby); //'123'
Person.sayHobby('baskstball'); //'123 baskstball'
如果没有静态属性,函数可以怎么写?
interface IPerson {
name: string;
sayName: (a: string) => void;
//简写上面:sayName();
}
class Person implements IPerson {
name ='123';
sayName(c: string) {
console.log(this.name, c);
}
constructor(a:string) {
this.name = a;
};
}
//写法1
function createPerson(c:{new (a: string): IPerson;}): IPerson{
return new c('zhangsan');
}
//写法2
function createPerson(c:new (a: string) => IPerson): IPerson{
return new c('zhangsan');
}
//写法3
// 抽象泛型,T可以理解为一个泛型变量,属于类型变量,这里属于IPerson,接口继承接口,实现接口的抽象
function createPerson <T extends IPerson>(c:new (a: string) => T): T{
return new c('zhangsan');
}
注意两个ts配置:
"strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */
"strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
接口继承接口
接口继承接口,相当于接口的拓展。
interface Shape {
color: string;
}
interface Square extends Shape {
sideLength: number;
}
let a:Square = {
color: 'white',
sideLength: 60
}
一个接口可以继承多个接口,创建出多个接口的合成接口。
interface Shape {
color: string;
}
interface PenStroke {
penWidth: number;
}
interface Square extends Shape, PenStroke{
sideLength: number;
}
let a:Square = {
color: 'white',
sideLength: 60,
penWidth: 30
}
type是类型别名,给交叉类型赋别名
type ShapeAndPenStroke = Shape & PenStroke
interface Square1 extends ShapeAndPenStroke{
sideLength: number;
}
交叉类型:两个都包括:Shape & PenStroke
联合类型:两个取其一:Shape | PenStroke
类型断言
清楚地知道一个实体的类型,在赋值时人为确定类型,不需要ts进行类型推断。
两种写法:
-
值
as
类型 -
<类型>
值
interface Shape {
color: string;
}
interface PenStroke {
penWidth: number;
}
interface Square extends Shape, PenStroke {
sideLength: number;
}
// let square = <Square>{};
let square = {} as Square;
square.color = "blue";
square.sideLength = 10;
square.penWidth = 5.0;
混合类型
混合类型:一个接口中有函数、有属性
interface Counter {
(start: number): string;
interval: number;
reset(): void;
}
function getCounter(): Counter {
let counter = <Counter>function (start: number) { };
counter.interval = 123;
counter.reset = function () { };
return counter;
}
let c = getCounter();
c(10);
c.reset();
c.interval = 5.0;