TypeScript 接口
- 接口用于对 json 数据进行约束
- 使用接口之前 ts 函数自定义传入参数:
ts
function printLabel(labelInfo:{label:string}):void { }
printLabel('hahah'); // 错误
printLabel({name:'张三'}); // 错误
printLabel({label:'张三'}); // 正确
- 使用接口约束 使用
interface
关键字
ts
interface Obj {
name: string; // ; 结尾,以,结束不会报错,但代码格式化也会替换成;
age: number;
}
function fn(params: Obj) {
console.log(params);
}
fn({ name: "tom", age: 20 }); // 正确
fn({ name: "tom" }); // 错误,缺少 age 参数
属性类接口
可选参数
ts
interface Obj {
name: string; // 必须传入
age?: number; // 可选参数
}
function fn(params: Obj) {
console.log(params);
}
fn({ name: "tom", age: 20 }); // ok
fn({ name: "tom" }); // ok
只读属性
ts
interface Obj {
readonly name: string;
}
let a:Obj = {name: '123'}
a.name = 'str'; // 错误 不能设置只读属性
- 只读数组
ReadonlyArray
ts
let arr: ReadonlyArray<number> = [1]
arr.length = 2; // 错误
arr.push(2); // 错误
arr[0] = 2; // 错误
let a: number[] = [2]
a = arr; // 错误 ReadonlyArray 类型数组不能赋值给普通数组
a = arr as number[]; // ok 可以使用断言
函数类型接口
ts
interface myFunc{
/* 方法必须传入 str 与 keyWord 且返回 boolean */
(str: string, keyWord: string): boolean
}
/* 实现 */
const fn: myFunc = (str: string, key: string) => str.includes(key);
可索引接口
数组的约束
ts
interface myArr {
/* index 为键名,可以自定义。 :number 表示下标为数字类型 */
[index:number]: number;
}
let arr: myArr = [1]
对象的约束
ts
interface myObj {
/* prop 为键名,可以自定义。 :string 表示下标为字符串类型 */
[prop:string]: number;
}
let arr:myObj ={ a: 2 }
额外的属性检查
ts
interface Config {
color?: string;
len?: number;
}
function fn(option:Config){}
fn({color:'#fff',myKey: 'value'}) // myKey 在定义的接口中不存在,ts 会报错
// 要传入额外的属性
// 1. 使用类型断言
fn({color:'#fff',myKey: 'value'} as Config) // ok
// 2. 添加接口的约束
interface newConfig {
color?: string;
len?: number;
[prop:string]: any;
}
function fn1(option:newConfig){}
fn1({color:'#fff',myKey: 'value'}) // ok
类类型接口
implements 关键字
ts
interface Animal{
name:string; // 需要有 name 属性
myFn(str:string):void; // 需要有 myFn 方法
}
/* implements 关键字实现 Animal 接口 */
class Dog implements Animal{
name:string; // 接口定义的是公有属性,不会检查静态私有属性
constructor(name:string){
this.name = name;
}
myFn(str: string): void {
console.log(str);
}
}
const d: Dog=new Dog('小黑');
d.myFn('str');
约束 constructor 构造器
由于接口不会检查类中的静态部分,所以下面示例中会报错:
ts
interface ClockConstructor {
/* new 表示构造器 */
new (hour: number, minute: number);
}
class Clock implements ClockConstructor {
currentTime: Date | undefined;
constructor(h: number, m: number) { } // constructor存在于类的静态部分
}
解决办法:
ts
/* 定义两个接口 */
interface myConstructor {
new (hour: number):myInterface; /* 构造器返回另一个接口 */
}
interface myInterface { }
/* 创建一个构造函数*/
function myCreate(cons: myConstructor,hour: number): myInterface{
return new cons(hour)
}
class myClass implements myInterface {
constructor(h: number) { }
}
// 使用
myCreate(myClass,1) // ok
接口扩展
接口继承
ts
interface myInter1 {
name: string;
}
/* 继承 */
interface myInter2 extends myInter1{
myFn():void;
}
/* 实现 */
class Person implements myInter2 {
name: string= 'tom';
myFn(): void {
}
}
继承多个接口
ts
interface myInter1 {
name: string;
}
interface myInter2 {
age: number;
}
/* 继承 */
interface myInter3 extends myInter1,myInter2{
myFn():void;
}
/* 实现 */
class Person implements myInter2 {
name: string= 'tom';
age: number=12
myFn(): void {
}
}
子类约束继承接口
ts
interface myInter1 {
name: string;
}
interface myInter2 {
age: number;
}
/* 继承 */
interface myInter3 extends myInter1, myInter2 {
myFn(): void;
}
class Person {
name: string = "str";
}
/* 实现 */
class Son extends Person implements myInter3 {
age: number = 2;
myFn(): void {
}
}
- 接口与接口直接 extends 继承
- 类使用 implements 实现
- 都可以使用多个接口,类中必须实现接口中的所有方法