美文网首页
TypeScript的应用方式

TypeScript的应用方式

作者: 冰蓝泪 | 来源:发表于2021-02-25 14:57 被阅读0次

    > 本文不讲如何安装,只讲代码中的实际应用

    # 一、什么是 TypeScript?

    typescript是js的超集,它在js的基础上增加了静态类型校验,可以在运行前校验js中的一些错误并修正。

    在定义类型之后,js中任何地方都会有文档提示,对象中包含的值都可以提示出来,这一点让js变得相当友好。

    那么想要在已有项目中增加ts需要怎么做?

    ts支持渐进式迁移,可配置只检查部分文件,在已有项目中慢慢改造。ts的类型检查不会影响js代码的执行、这意味着,即便类型校验有错误,代码依旧运行良好。

    ts的困难在于它需要定义所有的值类型,这个工作量还是蛮大的。

    # 二、ts的简单使用

    **ts的类型定义语法如下**

    - 基础类型:

    ```javascript

    let isDone: Boolean = false;

    let str: String = '';

    let count: Number = 1;

    // 使用联合操作符

    let some1: Number | String = 1;

    let some2: Number | String = '1';

    ```

    - 数组

    ```javascript

    let arr1: number[] = [1,2];

    let arr2: Array<string> = ['1','2']; // 泛型写法,下面会讲

    let arr3: [string,boolean] = ['1',false]; // 元组-定义已知数量和类型

    ```

    - 对象(当存在复杂对象时,使用接口和类来声明,后面会讲)

    ```javascript

    let obj: {a: string, b: number } = {a: '我是字符串',b: 2};

    ```

    - any

    ```javascript

    let something: any = 'asd';

    ```

    any用来表示任何类型,ts不会对它进行校验。

    >  如果你的ts代码中到处都是any,建议不要使用ts更方便些。

    - viod、null、undefined、never

    这些值基本没什么用,有兴趣可以自己查看[文档](https://www.tslang.cn/docs/handbook/basic-types.html)

    - 枚举 **enum**

    **enum**类型是对JavaScript标准数据类型的一个补充。 使用枚举类型可以为一组数值赋予友好的名字。

    ```javascript

    enum Color {Red, Green, Blue} // 默认情况下,从0开始为元素编号。

    let c: Color = Color.Green; // => 1

    //你也可以手动的指定成员的数值。 例如,我们将上面的例子改成从 1开始编号:

    enum Color {Red = 1, Green, Blue}

    let c: Color = Color.Green; // => 2

    ```

    它不但可以使用key获取value,还可以使用value获取key。

    ```javascript

    enum Color {Red=1, Green, Blue}

    let colorName: string = Color[2]; // => 'Green'

    ```

    # 三、ts进阶使用

    ## 类型断言

    当你确定某个值的类型时,你可以指定它的类型。它有两种写法:

    尖括号写法

    ```javascript

    let someValue: any = "this is a string"; // any未知类型

    let str: string = someValue; // error someValue不是string类型

    // 断言为string,校验成功

    let str: string = <string>someValue;

    ```

    as写法

    ```javascript

    let someValue: any = "this is a string";

    let str: string = someValue as string

    ```

    ## 接口interface

    interface用来定义复杂类型(对象、函数、索引类型等)

    ```javascript

    interface Config {

      readonly color: string; // 定义只读

      width?: number; // 定义可选属性

    }

    function doSome( option: Config ){

      // option.color

      // option.width

    }

    ```

    同一作用域中同名的interface会自动合并

    ```javascript

    interface Config {

      color: string;

      width: number;

    }

    // 同一作用域中

    interface Config {

      height: number;

    }

    // 会合并为

    interface Config {

      color: string;

      width: number;

      height: number;

    }

    ```

    extentds (interface可以使用extentds进行拓展)

    ```javascript

    interface Parent{

      readonly color: string; // 可定义常量

      width: number;

    }

    interface Children extends Parent{

      height: number;

    }

    ```

    ## 类

    公共,私有 与 存取

    1、public

    ```javascript

    class Animal {

        name: string; // 默认为public

        public id: string; // 也可以标明public

    }

    ```

    2、private

    ```javascript

    class Animal {

        // private 禁止在类的外部访问

        private move() {

    // dosomething

        }

    }

    new Animal().move; // 错误: 'move' 是私有的.

    ```

    3、get、set

    TypeScript支持通过getters/setters来截取对对象成员的访问。与vue的watcher同理。

    ```javascript

    class Animal {

        get fullName(): string {

            return this._fullName;

        }

        set fullName(newName: string) {

            // dosomething

        }

    }

    ```

    4、readonly标明只读

    ```javascript

    class Animal {

        readonly number: number = 8;

    }

    ```

    还有static、protected等,这里不过多说明,详情请看[文档。](https://www.tslang.cn/docs/handbook/classes.html)

    ## 函数

    函数类型包含两部分:参数类型和返回值类型。

    ```javascript

    // :number 表示返回值为number

    function add(x: number, y: number): number {

        return x + y;

    }

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

    ```

    声明一个未赋值函数

    ```javascript

    let fn: (x: number, y: number) => number;

    fn = myAdd;

    ```

    除此之外,interface同样可以声明函数类型

    ```javascript

    // : boolean表示返回值为布尔值

    interface Func {

      (source: string, subString: string): boolean;

    }

    // 命名为x,y或者其他都可以

    let ff: Func = (x: string, y: string): boolean => {

    return x === y

    }

    ```

    函数参数类型只会校验它的类型,不会校验它的名字

    ## type类型别名

    类型别名会给一个类型起个新名字。它可以作用于原始值,联合类型,元组以及其它任何你需要手写的类型。它的语法看起来像是普通的js。

    ```java

    // 给String重新命名

    type Easing = String

    // 定义联合类型

    type Easing = 'a' | 'b' | 'c'

    ```

    type可以将多个interface联合或者交叉

    ```java

    interface A{

        kind: "square";

        size: number;

    }

    interface B{

        kind: "rectangle";

        width: number;

        height: number;

    }

    interface C{

        kind: "circle";

        radius: number;

    }

    type Shape1 = A | B | C; // 联合

    type Shape2 = A & B & C; // 交叉

    ```

    type也可以声明函数和元组

    ```java

    // 函数

    type Easing = () => string

    // 元组

    type DudeType = {

      [key in Keys]: string // keys是一个索引类型

    }

    ```

    > type和interface功能类似,但type更像一个值而不是一个类型。在两者都能实现需求的情况下,官方建议优先使用interface。

    # 四、ts高级用法--泛型

    考虑到代码的可重用性和拓展性,ts允许使用泛型来定义未知类型,使用尖括号语法。

    ```javascript

    // 当入参未知时,我们可定义一个泛型

    function identity<T>(arg: T): T {

        return arg;

    }

    // 它可以这样用,表示数组

    function identity<T>(arg: T[]): T[] {

        return arg;

    }

    // 或者表示对象

    function identity<T>(arg: {x: T, y: T}): T {

        return arg.x;

    }

    ```

    泛型支持extends语法

    ```javascript

    interface Lengthwise {

        length: number;

    }

    function loggingIdentity<T extends Lengthwise>(arg: T): T {

        console.log(arg.length);  // 可以用时length属性

        return arg;

    }

    ```

    泛型promise使用示例

    ```typescript

    // Promise<T>表示Promise.resolve的值类型是T

    // catch类型默认是any

    let ajax = <T>(params: any): Promise<T> => {

      return new Promise((resolve) => {

        axios.get('/list').then(res=> {

          resolve(params)

        })

      })

    }

    // 使用时

    ajax<{a: string,b:number}>(params).then(res=>{

        // res 类型为{a: string,b:number}

    )

    ```

    >此处只讲了typescript的一些常见用法和问题,更多说明请看官方文档。[(中文文档3.1](https://www.tslang.cn/docs/release-notes/typescript-3.1.html),[英文文档4.1)](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-1.html)

    ==一些运算操作符==

    1. !断言此处有值。

    ```javascript

    let y!:number = 1; // 表示y必定有值

    ```

    2. ?表示可能未定义。

    ```javascript

    let obj = {

        y?: number, // 相当于  number | undefined

        z: string

    }

    let num: number;

    num = obj.y; // error,不能将类型“number | undefined”分配给类型“number”。

    ```

    3. ?? 空值合并。

    通常我们取一个可能存在的值时,会像这样

    ```javascript

    let obj = {

        y?: number

    }

    let num: number;

    num = obj.y || 1;

    ```

    但当obj.y为0时,它会存在问题。所以ts提供了更好的解决方案。??只会判断null和undefined两个值。

    ```javascript

    let obj = {

        y?: number

    }

    let num: number;

    num = obj.y ?? 1; // 即使y为0,也会得到0,而不是1

    ```

    4.!取值用法和?的赋值用法。

    !表示必定有值,?表示可能有值,所以他们也可以这样使用

    当你确定值必定存在时

    ```javascript

    let obj: {

        a?: {

              b?: number

    }

    } = { a: { b: 1 } };

    let x: number = obj.a.b; // 报错,对象可能未定义

    let y: number = obj!.a!.b; // 通过

    ```

    当你不确定值是否存在

    ```javascript

    let obj: {

          a?: {

            b?: number

          }

        }

    obj.a.b = 1; // 报错

    obj?.a?.b = 1; // 通过

    ```

    5. !(放在value之后)允许null和undefined

    ```javascript

    let y:number

    y = null // 无法通过编译

    y = undefined // 无法通过编译

    y = null!      // 通过

    y = undefined! // 通过

    ```

    6. 最新特性??=、||=、&&= 

    有时候我们需要对可能存在的值给一个默认值

    ```javascript

    let obj = {

        y?: number

    }

    // 正常情况

    obj.y = obj.y ? obj.y : 1;

    // 使用??空值合并

    obj.y = obj.y ?? 1;

    // 使用??=运算符,他看起来有点像 +=和-=

    obj.y ??= 1;

    ```

    相关文章

      网友评论

          本文标题:TypeScript的应用方式

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