• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

TypeScript接口、type关键字可读、只读属性、继承接口|类、规范类、函数|可索引|类|混合类型接口、ReadonlyArray、接口和amp;type、映射类型

武飞扬头像
YF-SOD
帮助1

目录

TypeScript接口

可选属性

 :?

只读属性

ReadonlyArray

接口继承接口(extends)

接口继承类(extends)

接口规范类(implements)

函数类型接口

可索引类型接口

只读设置

类类型接口

规定构造函数 

混合类型接口

type关键字

type扩展(&)

interface继承type

映射类型

type高级使用


TypeScript接口

用于规范定义变量的类型,规定变量应该具有什么属性或函数入参什么值返回什么值等。

  1.  
    interface IUser {
  2.  
    name: string
  3.  
    age: number
  4.  
    }
  5.  
    let user: IUser = { name : 'yf', age: 32 }

可选属性

带有可选属性的接口与普通的接口定义差不多,只是在可选属性名字定义的后面加一个?符号。定义的属性可以不用实现。

  1.  
    interface IUser {
  2.  
    name: string
  3.  
    age?: number
  4.  
    }
  5.  
    let user: IUser = { name : 'yf' }

 :?

注意区分冒号后也可以接问号。

  1.  
    const gender: ?number = undefined;
  2.  
    // 等同于下面这种写法
  3.  
    const gender: number | null | void = undefined

只读属性

只读属性只能在对象刚刚创建的时候修改其值。 在属性名前用readonly来指定只读属性 。

  1.  
    interface Point {
  2.  
    readonly x: number;
  3.  
    readonly y: number;
  4.  
    }
  5.  
    let p1: Point = { x: 10, y: 20 };
  6.  
    p1.x = 5; // error!

ReadonlyArray<T>

表示数组创建后再也不能被修改

  1.  
    let a: number[] = [1, 2, 3, 4];
  2.  
    let ro: ReadonlyArray<number> = a;
  3.  
    ro[0] = 12; // error!
  4.  
    ro.push(5); // error!
  5.  
    ro.length = 100; // error!
  6.  
    a = ro; // error!

注意最后a=ro,将ReadonlyArray赋值到一个普通数组也是不可以的。 但是你可以用类型断言重写

a = ro as number[];

接口继承接口(extends)

一个接口可以继承多个接口,创建出多个接口的合成接口,继承的每个接口里的内容都需要满足

  1.  
    interface Shape {
  2.  
    color: string;
  3.  
    }
  4.  
    interface PenStroke {
  5.  
    penWidth: number;
  6.  
    }
  7.  
    interface Square extends Shape, PenStroke {
  8.  
    sideLength: number;
  9.  
    }
  10.  
    let square:Square = {
  11.  
    color: 'bule',
  12.  
    sideLength: 0,
  13.  
    penWidth: 0
  14.  
    };

接口继承类(extends)

当接口继承了一个类类型时,它会继承类的成员但不包括其实现。 就好像接口声明了所有类中存在的成员,但并没有提供具体实现一样。

例如下面接口继承了Control类,故接口约束的abc类中需要定义pubulic的state属性

  1.  
    class Control {
  2.  
    state: any;
  3.  
    }
  4.  
    interface SelectableControl extends Control {
  5.  
    select(): void;
  6.  
    }
  7.  
    class abc implements SelectableControl {
  8.  
    state: any
  9.  
    select() { }
  10.  
    }

注意接口也能继承到类的private和protected成员。但继承后这个接口类型只能被这个类或其子类所实现

 例如下面abc实现SelectableControl接口就必须是Control类的子类,因为state属性是私有属性。

  1.  
    class Control {
  2.  
    private state: any;
  3.  
    }
  4.  
    interface SelectableControl extends Control {
  5.  
    select(): void;
  6.  
    }
  7.  
     
  8.  
    class abc extends Control implements SelectableControl {
  9.  
    select() { }
  10.  
    }

接口规范类(implements)

相当于用接口规范便量时的冒号:,同样也可以通过逗号用多个接口约束一个类。

注意接口中定义的属性,必须在初始时定义,如果仅在constructor中定义也会报错,例如下面h不能仅在constructor中定义

  1.  
    interface ClockInterface {
  2.  
    tick();
  3.  
    }
  4.  
    interface Clock {
  5.  
    h: number
  6.  
    }
  7.  
    class DigitalClock implements ClockInterface,Clock {
  8.  
    //h: string //放开此行注释为正确的
  9.  
    constructor(h: number, m: number) { } //error缺少h属性
  10.  
    tick() {
  11.  
    console.log("beep beep");
  12.  
    }
  13.  
    }

函数类型接口

括号里为参数,冒号右边为函数的返回值。

函数的参数会逐个进行检查,只要求对应位置上的参数类型是兼容的。所以函数的参数名不需要与接口里定义的名字相同

  1.  
    interface SearchFunc {
  2.  
    (source: string, subString: string): boolean;
  3.  
    }
  4.  
    let mySearch: SearchFunc = function(so: string, su: string) {
  5.  
    let result = so.search(su);
  6.  
    return result > -1;
  7.  
    }

可索引类型接口

可索引类型具有一个索引签名,它描述了对象索引的类型,还有相应的索引返回值类型。 

它共有支持两种索引签名:字符串和数字。

注意同时使用两种类型的索引时,数字索引的返回值必须是字符串索引返回值类型的子类型。 这是因为当使用number来索引时,JavaScript会将它转换成string然后再去索引对象。 也就是说用100(一个number)去索引等同于使用"100"(一个string)去索引,因此两者需要保持一致。 

  1.  
    class Animal {
  2.  
    name: string;
  3.  
    }
  4.  
    class Dog extends Animal {
  5.  
    breed: string;
  6.  
    }
  7.  
    interface NotOkay {
  8.  
    [x: number]: Animal;
  9.  
    [x: string]: Dog;
  10.  
    }// 错误:使用'string'索引,有时会得到Animal,数字索引应该是字符串索引的子集
  11.  
     
  12.  
    interface NotOkay {
  13.  
    [x: number]: Dog;
  14.  
    [x: string]: Animal;
  15.  
    }//OK
学新通

 注意使用了可索引类型后,另外定义的属性需要符合可索引。例如下面额外定义了字符串name属性,而使用的可索引也是字符串,所以指向的值应该相同。

  1.  
    interface NumberDictionary {
  2.  
    [index: string]: number;
  3.  
    length: number; // 可以,length是number类型
  4.  
    name: string // 错误,`name`的类型与索引类型返回值的类型不匹配
  5.  
    }

只读设置

可以将索引签名设置为只读,这样就防止了给索引赋值 

  1.  
    interface ReadonlyStringArray {
  2.  
    readonly [index: number]: string;
  3.  
    }
  4.  
    let myArray: ReadonlyStringArray = ["Alice", "Bob"];
  5.  
    myArray[2] = "Mallory"; // error!

类类型接口

接口描述了类的公共部分,而不是公共和私有两部分。 它不会检查类是否具有某些私有成员。 

  1.  
    interface ClockInterface {
  2.  
    currentTime: Date;
  3.  
    }
  4.  
     
  5.  
    class Clock implements ClockInterface {
  6.  
    private currentTime: Date;//error ,只能为public
  7.  
    constructor(h: number, m: number) { }
  8.  
    }

规定构造函数 

注意类是具有两个类型的:静态部分的类型和实例的类型 , constructor存在于类的静态部分,所以不在检查的范围内。

故下面通过在接口里new定义构造函数会报错

  1.  
    interface ClockConstructor {
  2.  
    new (hour: number, minute: number);
  3.  
    }
  4.  
     
  5.  
    class Clock implements ClockConstructor { //error,接口中的new无法直接在类里面实现
  6.  
    currentTime: Date;
  7.  
    constructor(h: number, m: number) { }
  8.  
    }

 但是我们可以借助函数的的形式去实现,例如下面

  1.  
    interface ClockInterface {
  2.  
    tick();
  3.  
    }
  4.  
    class DigitalClock implements ClockInterface {
  5.  
    constructor(h: number, m: number) { }
  6.  
    tick() {
  7.  
    console.log("beep beep");
  8.  
    }
  9.  
    }
  10.  
    class AnalogClock implements ClockInterface {
  11.  
    constructor(h: number, m: number) { }
  12.  
    tick() {
  13.  
    console.log("tick tock");
  14.  
    }
  15.  
    }
  16.  
    interface ClockConstructor {
  17.  
    new (hour: number, minute: number): ClockInterface;
  18.  
    }
  19.  
    function createClock(ctor: ClockConstructor, hour: number, minute: number){
  20.  
    return new ctor(hour, minute);
  21.  
    }
  22.  
    let digital = createClock(DigitalClock, 12, 17);
  23.  
    let analog = createClock(AnalogClock, 7, 32);
学新通

混合类型接口

一个对象可以同时做为函数和对象使用,并带有额外的属性。

需要借助类型断言,例如下面:

  1.  
    interface Counter {
  2.  
    (start: number): string;
  3.  
    interval: number;
  4.  
    reset(): void;
  5.  
    }
  6.  
    function getCounter(): Counter {
  7.  
    let counter = <Counter>function (start: number) { };
  8.  
    counter.interval = 123;
  9.  
    counter.reset = function () { };
  10.  
    return counter;
  11.  
    }
  12.  
     
  13.  
    let c = getCounter();
  14.  
    c(10);
  15.  
    c.reset();
  16.  
    c.interval = 5.0;
学新通

type关键字

用于给类型起一个新名字,支持基本类型、联合类型、元祖及其它任何你需要的手写类型,常用于联合类型。

  1.  
    type test = number; //基本类型
  2.  
    let num: test = 10;
  3.  
    type userOjb = {name:string} // 对象
  4.  
    type getName = ()=>string // 函数
  5.  
    type data = [number,string] // 元组
  6.  
    type numOrFun = Second | getName // 联合类型

type扩展(&)

interface的扩展可以通过type交叉(&)类型实现。

  1.  
    type Name = {
  2.  
    name: string;
  3.  
    }
  4.  
    type User = Name & {age: number}
  5.  
    let stu:User={name: 'wang', age: 18}

 interface交叉(&)可以实现type类型。

  1.  
    interface Name {
  2.  
    name: string;
  3.  
    }
  4.  
    type User = Name & {
  5.  
    age: number;
  6.  
    }
  7.  
    let stu:User={name:'wang', age: 18}

interface继承type

接口可以继承type类型。

  1.  
    type Name = {
  2.  
    name: string;
  3.  
    }
  4.  
    interface User extends Name {
  5.  
    age: number;
  6.  
    }
  7.  
    let stu:User={name: 'wang', age: 89}

映射类型

type可以使用关键字生成映射类型。

  1.  
    type Keys = "name" | "sex"
  2.  
    type DuKey = {
  3.  
    [Key in Keys]: string //类似 for ... in
  4.  
    }
  5.  
    let stu: Dukey = {
  6.  
    name: 'wang'
  7.  
    sex: 'man'
  8.  
    }

type高级使用

补充:

  1.  
    // 将所有属性变成可选的
  2.  
    type Optional<T> = {
  3.  
    [key in keyof T]?: T[key];
  4.  
    }
  5.  
     
  6.  
    // 将某些属性变成必选的
  7.  
    type MyRequired<T, K extends keyof T> = T &
  8.  
    {
  9.  
    [key in K]-?: T[key];
  10.  
    };
  11.  
     
  12.  
    // 例如我们有个实体
  13.  
    type App = {
  14.  
    _id?: string;
  15.  
    appId: string;
  16.  
    name: string;
  17.  
    description: string;
  18.  
    ownerList: string[];
  19.  
    createdAt?: number;
  20.  
    updatedAt?: number;
  21.  
    };
  22.  
     
  23.  
    // 我们在更新这个对象/类型的时候,有些 key 是必填的,有些 key 是选填的,这个时候就可以这样子生成我们需要的类型
  24.  
    type AppUpdatePayload = MyRequired<Optional<App>, '_id'>
学新通

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgghafg
系列文章
更多 icon
同类精品
更多 icon
继续加载