Skip to content
此页目录
本文总阅读量

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 实现
  • 都可以使用多个接口,类中必须实现接口中的所有方法

评论

交流群