前端与typescript(下) | 青训营笔记

66 阅读4分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 5 天

重点内容

在本次课程中,我们主要关注的内容为typescript的基本使用,包括ts的接口、泛型、修饰器以及模块化。

知识点介绍

接口

定义

接口定义了某些类所需要遵守的规范,规定这些类里必须提供某些方法,提供这些方法的类就可以满足实际需要。 typescrip中的接口类似于java,同时还增加了更灵活的接口类型,包括属性、函数、可索引和类等。

用途

接口的用途就是对行为和动作进行规范和约束。接口中不能有方法体,只允许有方法定义。

函数类型接口

interface encrypt {
    (key: string, value: string): string;
}

var md5: encrypt = function (key: string, value: string): string {
    //模拟操作
    return key + "----" + value;
}
console.log(md5("name", "123"));

可索引型接口

可索引接口就是对数组、对象的约束,不常用。

//可索引接口,对数组的约束
interface UserArr {
    [index: number]: string
}
var arr1: UserArr = ["aaa", "bbb"];
console.log(arr1[0]);

//可索引接口,对对象的约束
interface UserObj {
    [index: string]: string
}
var arr2: UserObj = { name: '张三', age: '21' };
console.log(arr2);

类类型接口

类类型接口就是对类的约束。

interface Animal {
    name: string;
    eat(str: string): void;
}

class Dog implements Animal {
    name: string;
    constructor(name: string) {
        this.name = name;
    }
    eat() {
        console.log(this.name + "吃大骨头");
    }
}

var d = new Dog("小狼狗");
d.eat();

接口的继承

接口可以继承接口,接口之间和抽象类之间的继承都是单向单继承,但是实现接口的子类可以实现多个接口。

interface Person {
    eat(): void;
}

interface Programmer extends Person {
    code(): void;
}

interface Web {
    app(): void;
}

class WebProgrammer implements Person, Web {
    public name: string;
    constructor(name: string) {
        this.name = name;
    }
    eat() {
        console.log(this.name + "下班吃饭饭")
    }
    code() {
        console.log(this.name + "上班敲代码");
    }
    app() {
        console.log(this.name + "开发小程序");
    }
}

var w = new WebProgrammer("张三");
w.eat();
w.code();
w.app();

泛型

定义

泛型就是解决类、接口、方法的复用性、以及对不特定数据类型的支持。

泛型类

泛型类可以支持不特定的数据类型,要求传入的参数和返回的参数必须一致。

//类的泛型
class MinClas<T>{
    public list: T[] = [];
    add(value: T): void {
        this.list.push(value);
    }
    min(): T {
        var minNum = this.list[0];
        for (var i = 0; i < this.list.length; i++) {
            if (minNum > this.list[i]) {
                minNum = this.list[i];
            }
        }
        return minNum;
    }
}
//实例化类并且制定了类的T代表的类型是number
var m1 = new MinClas<number>();
m1.add(3);
m1.add(2);
console.log(m1.min());
//实例化类并且制定了类的T代表的类型是string
var m2 = new MinClas<string>();
m2.add('c');
m2.add('a');
console.log(m2.min());

泛型接口

//泛型接口
interface ConfigFn<T> {
    (value: T): T;
}

function getData<T>(value: T): T {
    return value;
}

var myGetData: ConfigFn<string> = getData;
console.log(myGetData('20'));

修饰器

定义

装饰器就是一个方法,可以注入到类、方法、属性或参数上来扩展类、方法、属性或参数的功能。 常见的装饰器有:类装饰器、方法装饰器、属性装饰器、参数装饰器。

类修饰器

普通装饰器(无法传参)

function logClass(params: any) {
    console.log(params);//params就是当前类
    params.prototype.apiUrl = "我是动态扩展的属性";
    params.prototype.run = function () {
        console.log("我是动态扩展的方法");
    }
}
@logClass
class HttpClient {

}
var http: any = new HttpClient();
console.log(http.apiUrl);
http.run();

装饰器工厂(可传参)

function logClass(params: string) {
    return function (target: any) {
        console.log(target);//target就是当前类
        console.log(params);//params就是当前类传递进来的参数
        target.prototype.apiUrl = params;
    }
}
@logClass("http://www.baidu.com")
class HttpClient {

}
var http: any = new HttpClient();
console.log(http.apiUrl);

属性修饰器

属性装饰器会被应用到属性描述上,可以用来监视、修改或者替换属性的值。

在运行时传入2个参数: 类的构造函数或原型对象以及成员的名字。

//属性装饰器
function logProperty(params: any) {//params就是当前类传递进来的参数
    return function (target: any, attr: any) {
        console.log(target);
        console.log(attr);
        target[attr] = params;
    }
}
class HttpClient {
    @logProperty("http://www.baidu.com")
    public url: any | undefined;
    getData() {
        console.log(this.url);
    }
}
var http = new HttpClient();
http.getData();

方法修饰器

方法装饰器会被应用到方法描述上,可以用来监视、修改或者替换方法定义。 在运行时传入3个参数:

类的构造函数或原型对象以及成员的名字、成员的属性描述符。

function get(params: any) {//params就是当前类传递进来的参数
    return function (target: any, methodName: any, desc: any) {
        console.log(target);
        console.log(methodName);
        console.log(desc);
        target.apiUrl = params;
        target.run = function () {
            console.log("run");
        }
    }
}

class HttpClient {
    public url: any | undefined;
    constructor() {
    }
    @get("http://www.baidu.com")
    getData() {
        console.log(this.url);
    }
}

var http: any = new HttpClient();
console.log(http.apiUrl);
http.run();

参数修饰器

参数装饰器表达式会在运行时当作函数被调用,可以使用参数装饰器为类的原型增加一些元素数据 ,传入下列3个参数: 类的构造函数或原型对象以及方法的名字、参数在函数参数列表中的索引。

function logParams(params: any) {
    return function (target: any, methodName: any, paramsIndex: any) {
        console.log(target);
        console.log(methodName);
        console.log(paramsIndex);
        target.apiUrl = params;
    }
}

class HttpClient {
    getData(@logParams("10086") uuid: any) {
        console.log(uuid);
    }
}

var http: any = new HttpClient();
http.getData(123456);
console.log(http.apiUrl);

修饰器的执行顺序

属性 > 方法 > 方法参数 > 类

模块化

模块化是指将一个大的程序文件,拆分成许多小的文件,然后将小文件组合起来。如CommonJS、AMD、CMD

好处

防止命名冲突、代码复用、高维护性

语法

模块功能主要由两个命令构成:export 和 import。

  • export 命令用于规定模块的对外接口
  • import 命令用于输入其它模块提供的功能

导入

// 引入 m1.js 模块内容
import * as m1 from "./model/m1";
m1.study();

个人总结

typescript与JavaScript在使用上有许多相通之处,在了解掌握js基本知识及使用的情况下对学习ts有一定帮助。

引用参考

link.juejin.cn/?target=htt…