• typescript部分笔记


    typescript
    
    安装
    
    npm install -g typescript
    
    
    
    创建一个文件 hello.ts
    
    随便输入内容
    
    
    然后编译
    
    tsc hello.ts
    
    
    
    ----------------------------
    
    声明变量
    
    let isDone: boolean = false;
    
    // 
    编译通过
    // 后面约定,未强调编译错误的代码片段,默认为编译通过
    
    
    ----------------------------
    
    
    使用 number 定义数值类型:
    
    
    let decLiteral: number = 6;
    
    let hexLiteral: number = 0xf00d;
    // ES6 中的二进制表示法
    
    let binaryLiteral: number = 0b1010;
    // ES6 中的八进制表示法
    
    let octalLiteral: number = 0o744;
    let notANumber: number = NaN;
    
    let infinityNumber: number = Infinity;
    
    
    
    ----------------------------
    
    字符串
    
    
    
    let myName: string = 'Tom';
    
    let myAge: number = 25;
    
    // 模板字符串
    
    let sentence: string = `Hello, my name is ${myName}.
    I'll be ${myAge + 1} years old next month.`;
    
    
    ----------------------------
    
    函数返回空值
    
    function alertName(): void {
        alert('My name is Tom');
    }
    
    
    ----------------------------
    
    
    任意值
    
    Any
    
    
    
    let myFavoriteNumber: string = 'seven';
    m
    yFavoriteNumber = 7;
    
    //上面的写法会报错
    
    
    
    //下面的就不会
    let myFavoriteNumber: any = 'seven';
    
    myFavoriteNumber = 7;
    
    
    
    
    any 可以在宽松模式下使用 或者在别的场景下使用
    
    
    
    ----------------------------
    
    
    联合类型
    
    
    let myFavoriteNumber: string | number;
    
    myFavoriteNumber = 'seven';
    
    myFavoriteNumber = 7;
    
    
    
    //访问联合类型的属性或方法
    function getLength(something: string | number): number 
    {
        return something.length;
    }
    
    --------------------------------------------------------
    
    对象的类型——接口
    
    
    interface Person {
        name: string;
        age: number;
    }
    
    let tom: Person = {
        name: 'Tom',
        age: 25
    };
    
    
    上面的例子中,我们定义了一个接口 Person,
    接着定义了一个变量 tom,它的类型是 Person。
    这样,我们就约束了 tom 的形状必须和接口 Person 一致。
    接口一般首字母大写
    
    
    
    --------------------------------------------------------
    对象的类型——接口
    
    interface Person {
        name: string;
        age?: number;
    }
    
    let tom: Person = {
        name: 'Tom'
    };
    
    
    有时我们希望不要完全匹配一个形状,那么可以用可选属性:
    
    
    
    
    --------------------------------------------------------
    
    对象的类型——接口
    
    
    有时候我们希望一个接口允许有任意的属性,可以使用如下方式:
    
    
    
    interface Person {
        name: string;
        age?: number;
        [propName: string]: any;
    }
    
    let tom: Person = {
        name: 'Tom',
        gender: 'male'
    };
    
    
    使用 [propName: string] 定义了任意属性取 string 类型的值。
    
    
    
    
    --------------------------------------------------------
    
    需要注意的是,一旦定义了任意属性,那么确定属性和可选属性的类型都必须是它的类型的子集:
    
    
    
    interface Person {
        name: string;
        age?: number;
        [propName: string]: string;
    }
    
    let tom: Person = {
        name: 'Tom',
        age: 25,
        gender: 'male'
    };
    
    
    
    上例中,任意属性的值允许是 string,
    但是可选属性 age 的值却是 number,number 
    不是 string 的子属性,所以报错了。
    
    另外,在报错信息中可以看出,此时
     { name: 'Tom', age: 25, gender: 'male' } 
    的类型被推断成了 { [x: string]: string | number;
     name: string; age: number; gender: string; },
    这是联合类型和接口的结合。
    
    
    --------------------------------------------------------
    
    
    接口 只读属性
    
    
    
    有时候我们希望对象中的一些字段只能在创建的时候被赋值,
    那么可以用 readonly 定义只读属性:
    
    
    
    interface Person {
        readonly id: number;
        name: string;
        age?: number;
        [propName: string]: any;
    }
    
    let tom: Person = {
        id: 89757,
        name: 'Tom',
        gender: 'male'
    };
    
    tom.id = 9527;//报错
    
    
    
    --------------------------------------------------------
    --------------------------------------------------------
    --------------------------------------------------------
    
    
    数组的类型
    
    
    在 TypeScript 中,数组类型有多种定义方式,比较灵活。
    
    
    最简单的方法是使用「类型 + 方括号」来表示数组:
    
    let fibonacci: number[] = [1, 1, 2, 3, 5];
    
    
    
    
    数组的项中不允许出现其他的类型:
    
    
    let fibonacci: number[] = [1, '1', 2, 3, 5];
    
    
    
    
    数组泛型
    
    
    我们也可以使用数组泛型(Array Generic) Array<elemType> 来表示数组:
    
    let fibonacci: Array<number> = [1, 1, 2, 3, 5];
    
    
    --------------------------------------------------------
    
    
    用接口表示数组
    
    
    
    接口也可以用来描述数组:
    
    interface NumberArray {
        [index: number]: number;
    }
    let fibonacci: NumberArray = [1, 1, 2, 3, 5];
    
    
    
    
    --------------------------------------------------------
    
    
    
    类数组
    
    
    上例中,arguments 实际上是一个类数组,不能用普通的数组的方式来描述,而应该用接口:
    
    
    function sum() {
        let args: number[] = arguments;
    }
    
    
    其中 IArguments 是 TypeScript 中定义好了的类型,它实际上就是:
    
    
    
    interface IArguments {
        [index: number]: any;
        length: number;
        callee: Function;
    }
    
    
    
    
    
    
    
    --------------------------------------------------------
    
    any 在数组中的应用
    
    
    
    一个比较常见的做法是,用 any 表示数组中允许出现任意类型:
    
    
    
    
    let list: any[] = ['xcatliu', 25, { website: 'http://xcatliu.com' }];
    
    
    
    
    --------------------------------------------------------
    
    
    函数的类型
    
    
    function sum(x: number, y: number): number {
        return x + y;
    }
    
    
    
    
    let mySum: (x: number, y: number) => number = function (x: number, y: number): number {
        return x + y;
    };
    
    
    在 TypeScript 的类型定义中,=> 用来表示函数的定义,
    左边是输入类型,需要用括号括起来,右边是输出类型。
    
    
    --------------------------------------------------------
    
    
    
    用接口定义函数的形状
    
    我们也可以使用接口的方式来定义一个函数需要符合的形状:
    
    
    interface SearchFunc {
        (source: string, subString: string): boolean;
    }
    
    let mySearch: SearchFunc;
    mySearch = function(source: string, subString: string) {
        return source.search(subString) !== -1;
    }
    
    
    --------------------------------------------------------
    
    
    可选参数
    
    前面提到,输入多余的(或者少于要求的)参数,是不允许的。那么如何定义可选的参数呢?
    
    
    
    function buildName(firstName: string, lastName?: string) {
        if (lastName) {
            return firstName + ' ' + lastName;
        } else {
            return firstName;
        }
    }
    let tomcat = buildName('Tom', 'Cat');
    let tom = buildName('Tom');
    
    
    需要注意的是,可选参数必须接在必需参数后面。
    换句话说,可选参数后面不允许再出现必需参数了:
    
    --------------------------------------------------------
    
    
    
    
    参数默认值
    
    
    在 ES6 中,我们允许给函数的参数添加默认值,
    TypeScript 会将添加了默认值的参数识别为可选参数:
    
    
    function buildName(firstName: string, lastName: string = 'Cat') {
        return firstName + ' ' + lastName;
    }
    let tomcat = buildName('Tom', 'Cat');
    let tom = buildName('Tom');
    
    此时就不受「可选参数必须接在必需参数后面」的限制了:
    
    
    
    function buildName(firstName: string = 'Tom', lastName: string) {
        return firstName + ' ' + lastName;
    }
    let tomcat = buildName('Tom', 'Cat');
    let cat = buildName(undefined, 'Cat');
    
    
    --------------------------------------------------------
    
    
    剩余参数
    ES6 中,可以使用 ...rest 的方式获取函数中的剩余参数(rest 参数):
    
    function push(array: any[], ...items: any[]) {
        items.forEach(function(item) {
            array.push(item);
        });
    }
    let a = [];
    push(a, 1, 2, 3);
    
    注意,rest 参数只能是最后一个参数,关于 rest 参数,可以参考 ES6 中的 rest 参数。
    
    
    
    --------------------------------------------------------
    
    
    https://ts.xcatliu.com/basics/type-of-function
    
    
    
    函数的类型
    
    重载
    
    重载允许一个函数接受不同数量或类型的参数时,作出不同的处理
    
    function reverse(x: number): number;
    function reverse(x: string): string;
    function reverse(x: number | string): number | string {
        if (typeof x === 'number') {
            return Number(x.toString().split('').reverse().join(''));
        } else if (typeof x === 'string') {
            return x.split('').reverse().join('');
        }
    }
    
    
    --------------------------------------------------------
    
    
    类型断言
    
    类型断言(Type Assertion)可以用来手动指定一个值的类型。
    
    
    <类型>值
    
    
    值 as 类型
    
    
    
    --------------------------------------------------------
    
    
    声明文件
    
    --------------------------------------------------------
    
    内置对象
    
    
    
    
    
    --------------------------------------------------------
    
    
    进阶
    
    
    类型别名
    
    
    type Name = string;
    type NameResolver = () => string;
    type NameOrResolver = Name | NameResolver;
    function getName(n: NameOrResolver): Name {
        if (typeof n === 'string') {
            return n;
        } else {
            return n();
        }
    }
    
    
    --------------------------------------------------------
    
    字符串字面量类型
    
    字符串字面量类型用来约束取值只能是某几个字符串中的一个。
    
    
    
    type EventNames = 'click' | 'scroll' | 'mousemove';
    function handleEvent(ele: Element, event: EventNames) {
        // do something
    }
    
    handleEvent(document.getElementById('hello'), 'scroll');  // 没问题
    handleEvent(document.getElementById('world'), 'dbclick'); // 报错,event 不能为 'dbclick'
    
    
    
    --------------------------------------------------------
    
    
    元组
    数组合并了相同类型的对象,而元组(Tuple)合并了不同类型的对象。
    
    
    
    简单的例子
    
    定义一对值分别为 string 和 number 的元组:
    
    
    
    let tom: [string, number] = ['Tom', 25];
    
    
    
    --------------------------------------------------------
    
    当赋值或访问一个已知索引的元素时,会得到正确的类型:
    
    let tom: [string, number];
    tom[0] = 'Tom';
    tom[1] = 25;
    
    tom[0].slice(1);
    tom[1].toFixed(2);
    
    
    
    
    也可以只赋值其中一项:
    
    let tom: [string, number];
    
    tom[0] = 'Tom';
    
    
    
    
    
    但是当直接对元组类型的变量进行初始化或者赋值的时候
    ,需要提供所有元组类型中指定的项。
    
    let tom: [string, number];
    
    tom = ['Tom', 25];
    
    
    let tom: [string, number];
    
    tom = ['Tom'];
    报错
    
    
    --------------------------------------------------------
    
    越界的元素
    
    当添加越界的元素时,
    它的类型会被限制为元组中每个类型的联合类型:
    
    
    
    let tom: [string, number];
    
    tom = ['Tom', 25];
    
    tom.push('male');
    
    tom.push(true);
    报错
    
    
    
    
    
    --------------------------------------------------------
    
    枚举
    
    枚举(Enum)类型用于取值被限定在一定范围内的场景,
    比如一周只能有七天,颜色限定为红绿蓝等。
    
    
    枚举使用 enum 关键字来定义:
    
    
    
    enum Days {Sun, Mon, Tue, Wed, Thu, Fri, Sat};
    
    
    
    
    --------------------------------------------------------
    
    enum Days {Sun, Mon, Tue, Wed, Thu, Fri, Sat};
    
    console.log(Days["Sun"] === 0); // true
    console.log(Days["Mon"] === 1); // true
    console.log(Days["Tue"] === 2); // true
    console.log(Days["Sat"] === 6); // true
    
    console.log(Days[0] === "Sun"); // true
    console.log(Days[1] === "Mon"); // true
    console.log(Days[2] === "Tue"); // true
    console.log(Days[6] === "Sat"); // true
    
    
    --------------------------------------------------------
    
    事实上,上面的例子会被编译为:
    
    
    var Days;
    (function (Days) {
        Days[Days["Sun"] = 0] = "Sun";
        Days[Days["Mon"] = 1] = "Mon";
        Days[Days["Tue"] = 2] = "Tue";
        Days[Days["Wed"] = 3] = "Wed";
        Days[Days["Thu"] = 4] = "Thu";
        Days[Days["Fri"] = 5] = "Fri";
        Days[Days["Sat"] = 6] = "Sat";
    })(Days || (Days = {}));
    
    
    
    --------------------------------------------------------
    
    
    手动赋值
    
    
    我们也可以给枚举项手动赋值:
    
    
    enum Days {Sun = 7, Mon = 1, Tue, Wed, Thu, Fri, Sat};
    
    console.log(Days["Sun"] === 7); // true
    console.log(Days["Mon"] === 1); // true
    console.log(Days["Tue"] === 2); // true
    console.log(Days["Sat"] === 6); // true
    
    
    
    --------------------------------------------------------
    
    上面的例子中,未手动赋值的枚举项会接着上一个枚举项递增。
    
    
    如果未手动赋值的枚举项与手动赋值的重复了,TypeScript 
    是不会察觉到这一点的:
    
    
    enum Days {Sun = 3, Mon = 1, Tue, Wed, Thu, Fri, Sat};
    
    console.log(Days["Sun"] === 3); // true
    console.log(Days["Wed"] === 3); // true
    console.log(Days[3] === "Sun"); // false
    console.log(Days[3] === "Wed"); // true
    
    
    上面的例子中,递增到 3 的时候与前面的 Sun 的取值重复了,
    但是 TypeScript 并没有报错,导致 Days[3] 的值先是 "Sun",
    而后又被 "Wed" 覆盖了。编译的结果是:
    
    
    var Days;
    (function (Days) {
        Days[Days["Sun"] = 3] = "Sun";
        Days[Days["Mon"] = 1] = "Mon";
        Days[Days["Tue"] = 2] = "Tue";
        Days[Days["Wed"] = 3] = "Wed";
        Days[Days["Thu"] = 4] = "Thu";
        Days[Days["Fri"] = 5] = "Fri";
        Days[Days["Sat"] = 6] = "Sat";
    })(Days || (Days = {}));
    --------------------------------------------------------
    
    手动赋值的枚举项可以不是数字,此时需要使用类型断言来让 tsc 
    无视类型检查 (编译出的 js 仍然是可用的):
    
    
    enum Days {Sun = 7, Mon, Tue, Wed, Thu, Fri, Sat = <any>"S"};
    
    var Days;
    (function (Days) {
        Days[Days["Sun"] = 7] = "Sun";
        Days[Days["Mon"] = 8] = "Mon";
        Days[Days["Tue"] = 9] = "Tue";
        Days[Days["Wed"] = 10] = "Wed";
        Days[Days["Thu"] = 11] = "Thu";
        Days[Days["Fri"] = 12] = "Fri";
        Days[Days["Sat"] = "S"] = "Sat";
    })(Days || (Days = {}));
    
    --------------------------------------------------------
    
    当然,手动赋值的枚举项也可以为小数或负数,
    此时后续未手动赋值的项的递增步长仍为 1:
    
    
    
    enum Days {Sun = 7, Mon = 1.5, Tue, Wed, Thu, Fri, Sat};
    
    console.log(Days["Sun"] === 7); // true
    console.log(Days["Mon"] === 1.5); // true
    console.log(Days["Tue"] === 2.5); // true
    console.log(Days["Sat"] === 6.5); // true
    
    --------------------------------------------------------
    
    class
    
    https://ts.xcatliu.com/advanced/class
    
    class Animal {
        public name;
        public constructor(name) {
            this.name = name;
        }
    }
    
    let a = new Animal('Jack');
    console.log(a.name); // Jack
    a.name = 'Tom';
    console.log(a.name); // Tom
    
    
    
    --------------------------------------------------------
    
    
    
    
    
    
    --------------------------------------------------------
    

      

    typescript
    安装
    npm install -g typescript


    创建一个文件 hello.ts
    随便输入内容

    然后编译
    tsc hello.ts


    ----------------------------
    声明变量
    let isDone: boolean = false;
    // 编译通过// 后面约定,未强调编译错误的代码片段,默认为编译通过

    ----------------------------

    使用 number 定义数值类型:

    let decLiteral: number = 6;
    let hexLiteral: number = 0xf00d;// ES6 中的二进制表示法
    let binaryLiteral: number = 0b1010;// ES6 中的八进制表示法
    let octalLiteral: number = 0o744;let notANumber: number = NaN;
    let infinityNumber: number = Infinity;


    ----------------------------
    字符串


    let myName: string = 'Tom';
    let myAge: number = 25;
    // 模板字符串
    let sentence: string = `Hello, my name is ${myName}.I'll be ${myAge + 1} years old next month.`;

    ----------------------------
    函数返回空值
    function alertName(): void {    alert('My name is Tom');}

    ----------------------------

    任意值
    Any


    let myFavoriteNumber: string = 'seven';myFavoriteNumber = 7;
    //上面的写法会报错


    //下面的就不会let myFavoriteNumber: any = 'seven';
    myFavoriteNumber = 7;



    any 可以在宽松模式下使用 或者在别的场景下使用


    ----------------------------

    联合类型

    let myFavoriteNumber: string | number;
    myFavoriteNumber = 'seven';
    myFavoriteNumber = 7;


    //访问联合类型的属性或方法function getLength(something: string | number): number {    return something.length;}
    --------------------------------------------------------
    对象的类型——接口

    interface Person {    name: string;    age: number;}
    let tom: Person = {    name: 'Tom',    age: 25};

    上面的例子中,我们定义了一个接口 Person,接着定义了一个变量 tom,它的类型是 Person。这样,我们就约束了 tom 的形状必须和接口 Person 一致。接口一般首字母大写


    --------------------------------------------------------对象的类型——接口
    interface Person {    name: string;    age?: number;}
    let tom: Person = {    name: 'Tom'};

    有时我们希望不要完全匹配一个形状,那么可以用可选属性:



    --------------------------------------------------------
    对象的类型——接口

    有时候我们希望一个接口允许有任意的属性,可以使用如下方式:


    interface Person {    name: string;    age?: number;    [propName: string]: any;}
    let tom: Person = {    name: 'Tom',    gender: 'male'};

    使用 [propName: string] 定义了任意属性取 string 类型的值。



    --------------------------------------------------------
    需要注意的是,一旦定义了任意属性,那么确定属性和可选属性的类型都必须是它的类型的子集:


    interface Person {    name: string;    age?: number;    [propName: string]: string;}
    let tom: Person = {    name: 'Tom',    age: 25,    gender: 'male'};


    上例中,任意属性的值允许是 string,但是可选属性 age 的值却是 number,number 不是 string 的子属性,所以报错了。
    另外,在报错信息中可以看出,此时 { name: 'Tom', age: 25, gender: 'male' } 的类型被推断成了 { [x: string]: string | number; name: string; age: number; gender: string; },这是联合类型和接口的结合。

    --------------------------------------------------------

    接口 只读属性


    有时候我们希望对象中的一些字段只能在创建的时候被赋值,那么可以用 readonly 定义只读属性:


    interface Person {    readonly id: number;    name: string;    age?: number;    [propName: string]: any;}
    let tom: Person = {    id: 89757,    name: 'Tom',    gender: 'male'};
    tom.id = 9527;//报错


    ------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    数组的类型

    在 TypeScript 中,数组类型有多种定义方式,比较灵活。

    最简单的方法是使用「类型 + 方括号」来表示数组:
    let fibonacci: number[] = [1, 1, 2, 3, 5];



    数组的项中不允许出现其他的类型:

    let fibonacci: number[] = [1, '1', 2, 3, 5];



    数组泛型

    我们也可以使用数组泛型(Array Generic) Array<elemType> 来表示数组:
    let fibonacci: Array<number> = [1, 1, 2, 3, 5];

    --------------------------------------------------------

    用接口表示数组


    接口也可以用来描述数组:
    interface NumberArray {    [index: number]: number;}let fibonacci: NumberArray = [1, 1, 2, 3, 5];



    --------------------------------------------------------


    类数组

    上例中,arguments 实际上是一个类数组,不能用普通的数组的方式来描述,而应该用接口:

    function sum() {    let args: number[] = arguments;}

    其中 IArguments 是 TypeScript 中定义好了的类型,它实际上就是:


    interface IArguments {    [index: number]: any;    length: number;    callee: Function;}






    --------------------------------------------------------
    any 在数组中的应用


    一个比较常见的做法是,用 any 表示数组中允许出现任意类型:



    let list: any[] = ['xcatliu', 25, { website: 'http://xcatliu.com' }];



    --------------------------------------------------------

    函数的类型

    function sum(x: number, y: number): number {    return x + y;}



    let mySum: (x: number, y: number) => number = function (x: number, y: number): number {    return x + y;};

    在 TypeScript 的类型定义中,=> 用来表示函数的定义,左边是输入类型,需要用括号括起来,右边是输出类型。

    --------------------------------------------------------


    用接口定义函数的形状
    我们也可以使用接口的方式来定义一个函数需要符合的形状:

    interface SearchFunc {    (source: string, subString: string): boolean;}
    let mySearch: SearchFunc;mySearch = function(source: string, subString: string) {    return source.search(subString) !== -1;}

    --------------------------------------------------------

    可选参数
    前面提到,输入多余的(或者少于要求的)参数,是不允许的。那么如何定义可选的参数呢?


    function buildName(firstName: string, lastName?: string) {    if (lastName) {        return firstName + ' ' + lastName;    } else {        return firstName;    }}let tomcat = buildName('Tom', 'Cat');let tom = buildName('Tom');

    需要注意的是,可选参数必须接在必需参数后面。换句话说,可选参数后面不允许再出现必需参数了:
    --------------------------------------------------------



    参数默认值

    在 ES6 中,我们允许给函数的参数添加默认值,TypeScript 会将添加了默认值的参数识别为可选参数:

    function buildName(firstName: string, lastName: string = 'Cat') {    return firstName + ' ' + lastName;}let tomcat = buildName('Tom', 'Cat');let tom = buildName('Tom');
    此时就不受「可选参数必须接在必需参数后面」的限制了:


    function buildName(firstName: string = 'Tom', lastName: string) {    return firstName + ' ' + lastName;}let tomcat = buildName('Tom', 'Cat');let cat = buildName(undefined, 'Cat');

    --------------------------------------------------------

    剩余参数ES6 中,可以使用 ...rest 的方式获取函数中的剩余参数(rest 参数):
    function push(array: any[], ...items: any[]) {    items.forEach(function(item) {        array.push(item);    });}let a = [];push(a, 1, 2, 3);
    注意,rest 参数只能是最后一个参数,关于 rest 参数,可以参考 ES6 中的 rest 参数。


    --------------------------------------------------------

    https://ts.xcatliu.com/basics/type-of-function


    函数的类型
    重载
    重载允许一个函数接受不同数量或类型的参数时,作出不同的处理
    function reverse(x: number): number;function reverse(x: string): string;function reverse(x: number | string): number | string {    if (typeof x === 'number') {        return Number(x.toString().split('').reverse().join(''));    } else if (typeof x === 'string') {        return x.split('').reverse().join('');    }}

    --------------------------------------------------------

    类型断言
    类型断言(Type Assertion)可以用来手动指定一个值的类型。

    <类型>值

    值 as 类型


    --------------------------------------------------------

    声明文件
    --------------------------------------------------------
    内置对象




    --------------------------------------------------------

    进阶

    类型别名

    type Name = string;type NameResolver = () => string;type NameOrResolver = Name | NameResolver;function getName(n: NameOrResolver): Name {    if (typeof n === 'string') {        return n;    } else {        return n();    }}

    --------------------------------------------------------
    字符串字面量类型
    字符串字面量类型用来约束取值只能是某几个字符串中的一个。


    type EventNames = 'click' | 'scroll' | 'mousemove';function handleEvent(ele: Element, event: EventNames) {    // do something}
    handleEvent(document.getElementById('hello'), 'scroll');  // 没问题handleEvent(document.getElementById('world'), 'dbclick'); // 报错,event 不能为 'dbclick'


    --------------------------------------------------------

    元组数组合并了相同类型的对象,而元组(Tuple)合并了不同类型的对象。


    简单的例子
    定义一对值分别为 string 和 number 的元组:


    let tom: [string, number] = ['Tom', 25];


    --------------------------------------------------------
    当赋值或访问一个已知索引的元素时,会得到正确的类型:
    let tom: [string, number];tom[0] = 'Tom';tom[1] = 25;
    tom[0].slice(1);tom[1].toFixed(2);



    也可以只赋值其中一项:
    let tom: [string, number];
    tom[0] = 'Tom';




    但是当直接对元组类型的变量进行初始化或者赋值的时候,需要提供所有元组类型中指定的项。
    let tom: [string, number];
    tom = ['Tom', 25];

    let tom: [string, number];
    tom = ['Tom'];报错

    --------------------------------------------------------
    越界的元素
    当添加越界的元素时,它的类型会被限制为元组中每个类型的联合类型:


    let tom: [string, number];
    tom = ['Tom', 25];
    tom.push('male');
    tom.push(true);报错




    --------------------------------------------------------
    枚举
    枚举(Enum)类型用于取值被限定在一定范围内的场景,比如一周只能有七天,颜色限定为红绿蓝等。

    枚举使用 enum 关键字来定义:


    enum Days {Sun, Mon, Tue, Wed, Thu, Fri, Sat};



    --------------------------------------------------------
    enum Days {Sun, Mon, Tue, Wed, Thu, Fri, Sat};
    console.log(Days["Sun"] === 0); // trueconsole.log(Days["Mon"] === 1); // trueconsole.log(Days["Tue"] === 2); // trueconsole.log(Days["Sat"] === 6); // true
    console.log(Days[0] === "Sun"); // trueconsole.log(Days[1] === "Mon"); // trueconsole.log(Days[2] === "Tue"); // trueconsole.log(Days[6] === "Sat"); // true

    --------------------------------------------------------
    事实上,上面的例子会被编译为:

    var Days;(function (Days) {    Days[Days["Sun"] = 0] = "Sun";    Days[Days["Mon"] = 1] = "Mon";    Days[Days["Tue"] = 2] = "Tue";    Days[Days["Wed"] = 3] = "Wed";    Days[Days["Thu"] = 4] = "Thu";    Days[Days["Fri"] = 5] = "Fri";    Days[Days["Sat"] = 6] = "Sat";})(Days || (Days = {}));


    --------------------------------------------------------

    手动赋值

    我们也可以给枚举项手动赋值:

    enum Days {Sun = 7, Mon = 1, Tue, Wed, Thu, Fri, Sat};
    console.log(Days["Sun"] === 7); // trueconsole.log(Days["Mon"] === 1); // trueconsole.log(Days["Tue"] === 2); // trueconsole.log(Days["Sat"] === 6); // true


    --------------------------------------------------------
    上面的例子中,未手动赋值的枚举项会接着上一个枚举项递增。

    如果未手动赋值的枚举项与手动赋值的重复了,TypeScript 是不会察觉到这一点的:

    enum Days {Sun = 3, Mon = 1, Tue, Wed, Thu, Fri, Sat};
    console.log(Days["Sun"] === 3); // trueconsole.log(Days["Wed"] === 3); // trueconsole.log(Days[3] === "Sun"); // falseconsole.log(Days[3] === "Wed"); // true

    上面的例子中,递增到 3 的时候与前面的 Sun 的取值重复了,但是 TypeScript 并没有报错,导致 Days[3] 的值先是 "Sun",而后又被 "Wed" 覆盖了。编译的结果是:

    var Days;(function (Days) {    Days[Days["Sun"] = 3] = "Sun";    Days[Days["Mon"] = 1] = "Mon";    Days[Days["Tue"] = 2] = "Tue";    Days[Days["Wed"] = 3] = "Wed";    Days[Days["Thu"] = 4] = "Thu";    Days[Days["Fri"] = 5] = "Fri";    Days[Days["Sat"] = 6] = "Sat";})(Days || (Days = {}));--------------------------------------------------------
    手动赋值的枚举项可以不是数字,此时需要使用类型断言来让 tsc 无视类型检查 (编译出的 js 仍然是可用的):

    enum Days {Sun = 7, Mon, Tue, Wed, Thu, Fri, Sat = <any>"S"};
    var Days;(function (Days) {    Days[Days["Sun"] = 7] = "Sun";    Days[Days["Mon"] = 8] = "Mon";    Days[Days["Tue"] = 9] = "Tue";    Days[Days["Wed"] = 10] = "Wed";    Days[Days["Thu"] = 11] = "Thu";    Days[Days["Fri"] = 12] = "Fri";    Days[Days["Sat"] = "S"] = "Sat";})(Days || (Days = {}));
    --------------------------------------------------------
    当然,手动赋值的枚举项也可以为小数或负数,此时后续未手动赋值的项的递增步长仍为 1:


    enum Days {Sun = 7, Mon = 1.5, Tue, Wed, Thu, Fri, Sat};
    console.log(Days["Sun"] === 7); // trueconsole.log(Days["Mon"] === 1.5); // trueconsole.log(Days["Tue"] === 2.5); // trueconsole.log(Days["Sat"] === 6.5); // true
    --------------------------------------------------------
    class
    https://ts.xcatliu.com/advanced/class
    class Animal {    public name;    public constructor(name) {        this.name = name;    }}
    let a = new Animal('Jack');console.log(a.name); // Jacka.name = 'Tom';console.log(a.name); // Tom


    --------------------------------------------------------





    --------------------------------------------------------












  • 相关阅读:
    【Android】HAL分析
    【qt】QT 的信号与槽机制
    【驱动】DM9000A网卡驱动框架源码分析
    【驱动】LCD驱动(FrameBuffer)分析
    告别我的OI生涯
    诸神的黄昏——北林退役帖合集
    cf592d
    北京林业大学就读体验
    hdu 5442 (ACM-ICPC2015长春网络赛F题)
    JAVA入门[4]-IntelliJ IDEA配置Tomcat
  • 原文地址:https://www.cnblogs.com/shaozhu520/p/12687352.html
Copyright © 2020-2023  润新知