认识typescript

97 阅读9分钟

今天是我参与第五届青训营伴学活动的第四天,今天学习了另外一门重要的编程语言——typescript。

TypeScript数据类型

变量格式一:

let 变量名: 变量类型 = 初始化值;

变量格式二:

let 变量名: 变量类型 | undefined; 变量名 = 变量值;

布尔类型

let flag: boolean = true; console.log(flag);

数字类型
整数型:

let num: number = 123; console.log(num);

浮点型:

let num: number = 3.1415926; console.log(num);

字符串类型

let str: string = "Hello,TypeScript"; console.log(str);

数组类型
第一种定义数组的方式:以数字类型数组为例

let arr: number[] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]; console.log(arr);

第二种定义数组的方式:以数字类型数组为例

let arr: Array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]; console.log(arr);

元组类型

元组属于数组的一种,元组中的元素可以不必全部保持类型一致!

let user: [number, string];
let userId = 10086;
let userName = "Nick";
let randomBoolean = true;

user = [userId, userName];      // 正确
user = [userId, randomBoolean]; // 错误
枚举类型
枚举类型的介绍:

随着计算机的不断普及,程序不仅只用于数值计算,还更广泛地用于处理非数值的数据。

例如:性别、月份、星期几、颜色、单位名、学历、职业等,都不是数值数据。

在其它程序设计语言中,一般用一个数值来代表某一状态,这种处理方法不直观,易读性差。

如果能在程序中用自然语言中有相应含义的单词来代表某一状态,则程序就很容易阅读和理解。

也就是说,事先考虑到某一变量可能取的值,尽量用自然语言中含义清楚的单词来表示它的每一个值,这种方法称为枚举方法,用这种方法定义的类型称枚举类型。

枚举类型的定义:
    标识符[= 整型常数/字符串],
    标识符[= 整型常数/字符串], 
    ...
    标识符[= 整型常数/字符串],
};
枚举类型的示例:
    success,
    error,
    overtime
};

let s: Flag = Flag.overtime;
console.log(s);//2

代码解读:如果标识符没有赋值,它的值就是下标。

    success = 200,
    error = 404,
    overtime = 500
};

let s: Flag = Flag.overtime;
console.log(s);//500

代码解读:如果标识符已经赋值,它的值就是被赋的值。

    success,
    error = 100,
    overtime
};

let s: Flag = Flag.overtime;
console.log(s);//101

代码解读:如果标识符没有赋值,它的值就是下标,如果从中间突然指定了一个值,那么它之后的值都会从当前值开始重新计算。

    Up = "UP",
    Down = "DOWN",
    Left = "LEFT",
    Right = "RIGHT",
}

let d: Direction = Direction.Up;
console.log(d);//UP
null类型

let n: null = null;

undefined类型

let u: undefined = undefined;

any类型

TypeScript 中的 void 类型表示任意数据类型。

enum Flag {
    success,
    error,
    overtime
};

let flag: any = true;//布尔型
let num: any = 123;//数字型
let str: any = 'Hello,TypeScript';//字符型
let arr: any = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0];//数组型
let tuple: any = [10086, 'Nick'];//元组型
let e: any = Flag.success;//枚举型
let n: any = null;//null型
let u: any = undefined;//undefined型
void类型

TypeScript 中的 void 类型表示没有任何类型,一般用于定义方法的时候方法没有返回值。

    console.log('执行成功了,我不需要返回值');
}
never类型

TypeScript 中的 never 类型是任何类型的子类型,也可以赋值给任何类型,但是没有类型是 never 的子类型或可以赋值给 never 类型, 即使 any 类型也不可以赋值给never。这意味着声明 never 类型的变量只能被 never 类型所赋值。

    throw new Error('抛出错误了');
}

组合类型

TypeScript 中支持一个变量可以赋予多种不同的变量类型,多个变量类型使用 | 分隔。


num = 3;
console.log(num);

num = null;
console.log(num);

num = undefined;
console.log(num);

TypeScript4函数

函数定义

函数是由一连串的子程序(语句的集合)所组成的,可以被外部程序调用,向函数传递参数之后,函数可以返回一定的值。

通常情况下,TypeScript 代码是自上而下执行的,不过函数体内部的代码则不是这样。如果只是对函数进行了声明,其中的代码并不会执行,只有在调用函数时才会执行函数体内部的代码。

函数格式
函数格式一:
    函数体 ...
    [return 返回值;]
}
函数格式二:
    函数体 ...
    [return 返回值;]
};
必选参数

必选参数:在调用函数的时候,必须要传入的参数,参数列表里边的参数默认就是必选参数,只要在声明的时候写了参数,在传递的时候,就必须传入参数,而且,实参与形参的数量与类型要一致。

    return `${name} --- ${age}`;
}

console.log(getInfo("张三", 28)); // 正确
console.log(getInfo("张三")); // 错误
console.log(getInfo(28)); // 错误
可选参数

必选参数:为了解决在函数传参的时候,某些参数可以不用传递,我们就需要可选参数了。

    return `${name} --- ${age}`;
}

console.log(getInfo("张三", 28)); // 正确
console.log(getInfo("张三")); // 正确
console.log(getInfo(28)); // 错误

注意:可选参数必须配置到参数的最后面。

默认参数

默认参数:为了解决在函数传参的时候,某些参数可以不用传递,但是我们又需要该参数的值,这时候我们就需要给这个参数设定一个默认值也叫初始化值,就得用到默认参数了。

    return `${name} --- ${age}`;
}

console.log(getInfo("张三", 28)); // 正确
console.log(getInfo("张三")); // 正确
console.log(getInfo(28)); // 错误

注意:可选参数不能够进行初始化值的设定。

剩余参数

剩余参数:在参数的类型确定而参数个数不确定的情况时,我们需要用到剩余参数,它使用 ... 将接收到的参数传到一个指定类型的数组中。

    let sum = 0;
    for (let i = 0; i < result.length; i++) {
        sum += result[i];
    }
    return sum;
}

console.log(sum(1, 2, 3, 4, 5, 6));

function sum(init: number, ...result: number[]): number {
    let sum = init;
    for (let i = 0; i < result.length; i++) {
        sum += result[i];
    }
    return sum;
}

console.log(sum(100, 1, 2, 3, 4, 5, 6));

注意:剩余参数必须配置到参数的最后面。

重载函数

重载指的是两个或者两个以上同名函数,但它们的参数不一样,这时会出现函数重载的情况。

TypeScript 中的重载是通过为同一个函数提供多个函数类型声明来实现函数重载的功能的。

function getInfo(name: string): string;
function getInfo(name: string, age: number): string;
//重载函数签名:就是把声明中出现的参数都写出来,如果可选,就使用可选参数,一个变量名可以使用多种类型用组合类型
function getInfo(name: string, age?: string | number): string {
    if (age) {

        return "我叫:" + name + ",年龄:" + age;
    } else {

        return "我叫:" + name;
    }
}

console.log(getInfo("zhangsan"));// 正确
console.log(getInfo("lisi", 20));// 正确
console.log(getInfo(123));// 错误
箭头函数

箭头函数其实就是简化了函数当作参数传递时匿名函数的写法,具体可参考ES6新特性。

    console.log("匿名函数执行了...");
}, 1000);

setTimeout(() => {
    console.log("箭头函数执行了...");
}, 1000);

TypeScript4类

类的定义
    name: string;//属性,前面省略了public关键词
    constructor(n: string) {//构造函数,实例化类的时候触发的方法
        this.name = n;//使用this关键字为当前类的name属性赋值
    }

    run(): void {//方法
        console.log(this.name+ "在跑步");
    }
}

var p = new Person("张三");
p.run();
类的继承

类的继承:在 TypeScript 中要想实现继承使用 extends 关键字,只要一旦实现了继承关系,那么子类中便拥有了父类的属性和方法,而在执行方法过程中,首先从子类开始找,如果有,就使用,如果没有,就去父类中找。类的继承只能单向继承。

    name: string;//父类属性,前面省略了public关键词

    constructor(n: string) {//构造函数,实例化父类的时候触发的方法
        this.name = n;//使用this关键字为当前类的name属性赋值
    }

    run(): void {//父类方法
        console.log(this.name + "在跑步");
    }
}

//中国人这个类继承了人这个类
class Chinese extends Person {
    age: number;//子类属性

    constructor(n: string, a: number) {//构造函数,实例化子类的时候触发的方法
        super(n);//使用super关键字调用父类中的构造方法
        this.age = a;//使用this关键字为当前类的age属性赋值
    }

    speak(): void {//子类方法
        super.run();//使用super关键字调用父类中的方法
        console.log(this.name + "说中文");
    }
}

var c = new Chinese("张三", 28);
c.speak();

修饰符

TypeScript 里面定义属性的时候给我们提供了 三种修饰符

public:公有类型,在当前类里面、子类、类外面都可以访问 protected:保护类型,在当前类里面、子类里面可以访问,在类外部没法访问 private:私有类型,在当前类里面可以访问,子类、类外部都没法访问 注意:如果属性不加修饰符,默认就是公有(public)。

静态属性

静态属性:被静态修饰符修饰的属性就是静态属性,静态属性可以通过类名直接调用。

    name: string;//属性,前面省略了public关键词
    static sex: string = "男";//被静态修饰符static修饰的属性

    constructor(n: string) {//构造函数,实例化类的时候触发的方法
        this.name = n;
    }

    run(): void {//方法
        console.log(this.name+ "在跑步");
    }
}

console.log(Person.sex);
静态方法

静态方法:被静态修饰符修饰的方法就是静态方法,静态方法可以通过类名直接调用,但是在静态方法内部,不能直接调用当前类的非静态属性、非静态方法。

    name: string;//属性,前面省略了public关键词
    static sex: string = "男";//被静态修饰符static修饰的属性

    constructor(n: string) {//构造函数,实例化类的时候触发的方法
        this.name = n;
    }

    run(): void {//方法
        console.log(this.name + "在跑步");
    }

    static print(): void {//被静态修饰符static修饰的方法
        // console.log('姓名:' + this.name);//错误
        console.log('性别:' + Person.sex);//正确
        // this.run();//错误
    }
}

Person.print();

抽象类

TypeScript 中的抽象类:它是提供其他类继承的基类,不能直接被实例化。

用abstract关键字定义抽象类和抽象方法,抽象类中的抽象方法不包含具体实现并且必须在派生类(也就是其子类)中实现,abstract抽象方法只能放在抽象类里面。

我们常常使用抽象类和抽象方法用来定义标准。

abstract class Animal {
    name: string;
    constructor(name: string) {
        this.name = name;
    }
    abstract eat(): any;//抽象方法不包含具体实现并且必须在派生类中实现
    run() {
        console.log(this.name + "会跑")
    }
}

class Dog extends Animal {
    constructor(name: string) {
        super(name);
    }
    eat(): any {//抽象类的子类必须实现抽象类里面的抽象方法
        console.log(this.name + "吃骨头");
    }
}

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

class Cat extends Animal {
    constructor(name: string) {
        super(name);
    }
    eat(): any {//抽象类的子类必须实现抽象类里面的抽象方法
        console.log(this.name + "吃老鼠");
    }
}

var c: Cat = new Cat("小花猫");
c.eat();
多态

多态:父类定义一个方法不去实现,让继承它的子类去实现 ,每一个子类有不同的表现,多态属于继承。