美文网首页
typescrit学习笔记(1)基础

typescrit学习笔记(1)基础

作者: 秋枫残红 | 来源:发表于2020-05-13 15:43 被阅读0次

    typescript学习(一)

    官网的介绍为:TypeScript 是 JavaScript 的类型的超集,它可以编译成纯 JavaScript。编译出来的 JavaScript 可以运行在任何浏览器上。实际上就是规定了一种强类型的写法,加入了一个将ts代码编译为js代码的过程,可以在编译过程中及时发现错误,而不是等到运行时在页面上瞎鸡儿点,然后发现是变量类型错误,变量名写错这种糟心的bug。这种的Uncaught TypeError就很影响写代码时的心情。

    安装与使用

    TypeScript 的命令行工具安装方法如下:

    npm install -g typescript
    

    以上命令会在全局环境下安装 tsc命令,安装完成之后,我们就可以在任何地方执行 tsc命令了。

    编译一个 TypeScript 文件很简单:

    tsc hello.ts
    

    我们约定使用 TypeScript 编写的文件以 .ts为后缀

    优势与不足

    TypeScript 增加了代码的可读性和可维护性

    • 类型系统实际上是最好的文档,大部分的函数看看类型的定义就可以知道如何使用了
    • 可以在编译阶段就发现大部分错误,这总比在运行时候出错好
    • 增强了编辑器和 IDE 的功能,包括代码补全、接口提示、跳转到定义、重构等

    TypeScript 非常包容

    • TypeScript 是 JavaScript 的超集,.js文件可以直接重命名为 .ts即可
    • 即使不显式的定义类型,也能够自动做出类型推论
    • 可以定义从简单到复杂的几乎一切类型
    • 即使 TypeScript 编译报错,也可以生成 JavaScript 文件
    • 兼容第三方库,即使第三方库不是用 TypeScript 写的,也可以编写单独的类型文件供 TypeScript 读取

    TypeScript 的缺点

    任何事物都是有两面性的,我认为 TypeScript 的弊端在于:

    • 有一定的学习成本,需要理解接口(Interfaces)、泛型(Generics)、类(Classes)、枚举类型(Enums)等前端工程师可能不是很熟悉的概念
    • 短期可能会增加一些开发成本,毕竟要多写一些类型的定义,不过对于一个需要长期维护的项目,TypeScript 能够减少其维护成本
    • 集成到构建流程需要一些工作量
    • 可能和一些库结合的不是很完美

    基本使用

    JavaScript 的类型分为两种:原始数据类型(Primitive data types)和对象类型(Object types)。

    原始数据类型包括:布尔值、数值、字符串、nullundefined以及 ES6 中的新类型 Symbol

    基本类型

    boolean

    布尔值是最基础的数据类型,在 TypeScript 中,使用 boolean定义布尔值类型:

    //编译通过
    let isDone: boolean = false;
    //使用构造函数生成的不是boolean值,而是一个对象
    let createdByNewBoolean: boolean = new Boolean(1);
    //可以使用Boolean方法返回一个boolean值
    let createdByBoolean: boolean = Boolean(1);
    

    数值

    ***

    字符串

    ***

    空值

    JavaScript 没有空值(Void)的概念,在 TypeScript 中,可以用 void表示没有任何返回值的函数:

    function alertName(): void {
        alert('My name is Tom');
    }
    

    声明一个 void类型的变量没有什么用,因为你只能将它赋值为 undefinednull

    let unusable: void = undefined;
    

    Null 和 Undefined

    在 TypeScript 中,可以使用 nullundefined来定义这两个原始数据类型:

    let u: undefined = undefined;
    let n: null = null;
    

    void的区别是,undefinednull是所有类型的子类型。也就是说 undefined类型的变量,可以赋值给 number类型的变量:

    // 这样不会报错
    let num: number = undefined;
    
    // 这样也不会报错
    let u: undefined;
    let num: number = u;
    

    any类型

    我们知道typescript是强类型的,因此是不允许在赋值过程中改变变量的类型,若变量的类型在程序运行过程中真的需要改变,那么我们可以将其定义为any类型

    let myFavoriteNumber: any = 'seven';
    myFavoriteNumber = 7;   
    

    对于未显式声明类型且未进行初始化的变量,它默认会被指定为any

    let something;
    something = 'seven';
    something = 7;
    

    对于未显式对于未显式声明类型但是进行过初始化的变量,会进行类型推断

    let myFavoriteNumber = 'seven';
    //事实上等同于
    let myFavoriteNumber: string = 'seven';
    

    联合类型

    我们也可以对一个变量指定多个类型,在赋值时,ts也根据所赋值进行类型推断

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

    并且我们可以访问这些类型的公共方法或者属性

    function getString(something: string | number): string {
        return something.toString();
    }
    

    Interfaces类型

    在 TypeScript 中,我们使用接口(Interfaces)来定义对象的类型。

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

    在使用定义的接口类型时,性新对象内少一些或者多一些属性都是不被允许的,有时我们希望不要完全匹配一个接口,那么可以用可选属性

    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'
    };
    

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

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

    此时会报错,age会被先于任意属性做匹配,此时需要的是string类型,可以该为下面这种用法

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

    只读属性

    有时候我们希望对象中的一些字段只能在创建的时候被赋值,那么可以用 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;
    
    // index.ts(14,5): error TS2540: Cannot assign to 'id' because it is a constant or a read-only property
    

    需要注意的是只读属性必须在给对象第一次赋值的时候进行设置

    数组类型

    简单用法

    //数组内只允许存入数值
    let fibonacci: number[] = [1, 1, 2, 3, 5];      
    

    泛型用法

    let fibonacci: Array<number> = [1, 1, 2, 3, 5];
    

    接口用法(不推荐)

    interface NumberArray {
        [index: number]: number;
    }
    let fibonacci: NumberArray = [1, 1, 2, 3, 5];
    

    需要注意的是类数组不是数组,它是一个区别于普通数组的对象

    函数类型

    函数声明

    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;
    };
    

    值得注意的是我们不止要对函数做出限制,也要对承载函数的那个变量做出限制,这里使用的=>与ES6中的=>是两码事。在 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='ccc', 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 = 'Tom', lastName: string) {
        return firstName + ' ' + lastName;
    }
    let tomcat = buildName('Tom', 'Cat');
    let cat = buildName(undefined, 'Cat');
    

    相关文章

      网友评论

          本文标题:typescrit学习笔记(1)基础

          本文链接:https://www.haomeiwen.com/subject/fegnnhtx.html