zoukankan      html  css  js  c++  java
  • 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


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





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












  • 相关阅读:
    第一节:SpringMVC概述
    SpringMVC【目录】
    Windows 系统快速查看文件MD5
    (error) ERR wrong number of arguments for 'hmset' command
    hive使用遇到的问题 cannot recognize input
    Overleaf支持的部分中文字体预览
    Understanding and Improving Fast Adversarial Training
    Django2实战示例 第十三章 上线
    Django2实战示例 第十二章 创建API
    Django2实战示例 第十一章 渲染和缓存课程内容
  • 原文地址:https://www.cnblogs.com/shaozhu520/p/12687352.html
Copyright © 2011-2022 走看看