美文网首页typescript
TS:TypeScript 简单入门

TS:TypeScript 简单入门

作者: limengzhe | 来源:发表于2021-09-13 16:57 被阅读0次

    本文首发于 TS:TypeScript 简单入门

    什么是 Typescript

    TypeScript 是 JavaScript 的超集。它基于 JavaScript 的类型定义提供了一个更加强大,更加灵活类型系统。目前由微软进行维护和管理。

    基本类型

    • 布尔值

      // 声明
      let isDone: boolean
      isDone = true // OK
      isDone = typeof 1 === "number" // OK
      isDone = "" // Type 'string' is not assignable to type 'boolean'.
      
    • 数字

      // 声明
      let index: number
      
      // 赋值
      index = 10 // OK
      index = "10" // Type 'string' is not assignable to type 'number'.
      
    • 字符串

      let myFavoriteNumber: string
      
      color = "seven" // OK
      color = 7 // Type 'number' is not assignable to type 'string'.
      
    • 数组

      let numberList: number[] // 只能存放 number 类型元素的数组,等价于 let numberList: Array<number>
      
      numberList = [1, 2, 3] // OK
      numberList = [1, 2, 3, "4"] // Type 'string' is not assignable to type 'number'.
      
    • 元组

      元组也是数组,但是元组中的元素类型可以被指定多种。

      let tuple: [string, number]
      
      tuple = ["hello", 10] // OK
      tuple = ["hello", 10, "world"] // Type 'string' is not assignable to type 'number'.
      

    对象类型

    对象是所有其他类型的超集,包括那些不可枚举的对象。要定义一个对象类型,只需列出它的属性及其类型即可,或者可以使用 object

    let person: {
      name: string
      age: number
    }
    
    let obj: object
    

    OK

    person = {
      name: "Tom",
      age: 10,
    }
    
    obj = { 1: "1", a: { b: "b" }, c: [1, 2, 3] }
    

    报错

    person = {
      name: "Tom",
      age: "10",
    } // Type 'string' is not assignable to type 'number'.
    
    obj = 1 // Type 'number' is not assignable to type 'object'.
    

    特殊类型(any、unknown、void、never)

    • any

      当不想让一个特殊值导致 TypeScript 在类型检查时抛出错误,可以使用 any

      let notSure: any
      

      OK

      notSure = false // OK
      notSure = 1 // OK
      notSure = "maybe a string instead" // OK
      notSure("hello") // OK
      
    • unknown

      类似于 any 类型,但不能作为函数执行。

      let notSure: unknown
      

      OK

      notSure = false // OK
      notSure = 1 // OK
      notSure = "maybe a string instead" // OK
      

      报错

      notSure("hello") // Object is of type 'unknown'.
      
      notSure.toFixed() // Property 'toFixed' does not exist on type 'unknown'.
      
    • void

      函数没有返回值时,可以使用 void

      function warnUser(): void {
        console.log("This is my warning message")
      }
      
    • never

      表示永远不存在的值的类型。当函数执行时抛出异常,或永远无法执行完毕,可以使用 never

      function error(message: string): never {
        throw new Error(message)
      }
      
      function infiniteLoop(): never {
        while (true) {}
      }
      

    联合类型

    联合类型(Union Types)表示取值类型可以为多种类型中的一种。

    let myFavoriteNumber: string | number
    
    myFavoriteNumber = "seven" // OK
    myFavoriteNumber = 7 // OK
    

    类型别名和接口

    当类型的定义较为复杂时或者需要复用时,可以给类型设置一个别名(Type Aliases),或者使用接口(Interface)定义。

    type Animal = {
      name: string
    }
    
    const cat: Animal = { name: "Tom" }
    

    等价于

    interface Animal {
      name: string
    }
    
    const cat: Animal = { name: "Tom" }
    

    可以通过下面方式实现类型和接口的继承

    type Bear = Animal & {
      honey: boolean
    }
    
    interface Bear extends Animal {
      honey: boolean
    }
    

    不过二者并不是完全相同的,类型别名不允许重复定义,而接口可以重复定义,并实现继承。

    OK

    interface Animal {
      name: string
    }
    
    interface Animal {
      age: number
    }
    
    const cat: Animal = { name: "Tom", age: 2 }
    

    报错

    type Animal = {
      name: string
    }
    
    // Duplicate identifier 'Animal'.
    type Animal = {
      age: number
    }
    

    类型断言

    有时候会遇到 TypeScript 无法识别的值类型信息,但你清楚知道它具有某种类型时,你可以用 as 操作符来进行类型断言。

    let someValue: any = "this is a string"
    let strLength: number = (someValue as string).length
    

    或者使用尖括号语法(除非代码在.tsx 文件中),与 as 是等价的

    let someValue: any = "this is a string"
    let strLength: number = (<string>someValue).length
    

    在函数中进行使用类型检查

    • 指定参数的类型

      function add(a: number, b: number) {
        return a + b
      }
      
      add(1, 2) // OK
      add("1", "2") // Error, 'string' is not assignable to 'number'
      
    • 指定返回值的类型

      function add(a: number, b: number): number {
        return a + b
      }
      
      let result: number = add(1, 2) // OK
      
    • 指定可选参数的类型

      function add(a: number, b?: number) {
        return a + (b || 0)
      }
      
      add(1) // OK
      add(1, 2) // OK
      add(1, "2") // Error, 'string' is not assignable to 'number'
      
    • 指定剩余参数的类型

      function add(a: number, ...rest: number[]) {
        return a + rest.reduce((p, n) => p + n, 0)
      }
      
      add(1) // OK
      add(1, 2, 3) // OK
      add(1, 2, "3") // Error, 'string' is not assignable to 'number'
      
    • 指定参数默认值的类型(可以,但没必要)

      function add(a: number = 0, b: number = 0) {
        return a + b
      }
      
      add() // OK
      add(1) // OK
      add(1, 2) // OK
      add(1, "2") // Error, 'string' is not assignable to 'number'
      

    枚举

    枚举是 TypeScript 对 JavaScript 语言运行时添加的一个特性。可以用来描述一组常量。

    • 数字枚举

      enum Color {
        Red,
        Green,
        Blue,
      }
      

      等价于

      const Color = {
        "0": "Red",
        "1": "Green",
        "2": "Blue",
        Red: 0,
        Green: 1,
        Blue: 2,
      }
      

      作为类型使用

      const c: Color = Color.Green
      
    • 在数字枚举中设置初始值

      上面代码中,我们看到了一个数字枚举,它的值是从 0 开始的。如果不想从 0 开始,可以使用如下方式来指定第一个值:

      enum Color {
        Red = 1,
        Green,
        Blue,
      }
      

      等价于

      const Color = {
        "1": "Red",
        "2": "Green",
        "3": "Blue",
        Red: 1,
        Green: 2,
        Blue: 3,
      }
      
    • 字符串枚举

      与数字枚举的不同之处在于,在字符串枚举中,每个成员都必须用字符串或另一个字符串枚举成员初始化。

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

      等价于

      const Direction = { Up: "UP", Down: "DOWN", Left: "LEFT", Right: "RIGHT" }
      

      作为类型使用

      const up: Direction = Direction.Up
      
    • 使用示例

      enum ShapeKind {
        Circle,
        Square,
      }
      
      interface Circle {
        kind: ShapeKind.Circle
        radius: number
      }
      
      interface Square {
        kind: ShapeKind.Square
        sideLength: number
      }
      
      let c: Circle = {
        kind: ShapeKind.Circle,
        radius: 100,
      }
      
      let s: Square = {
        kind: ShapeKind.Square,
        sideLength: 100,
      }
      
      function area(shape: Circle | Square): number {
        switch (shape.kind) {
          case ShapeKind.Circle:
            return Math.PI * shape.radius ** 2
          case ShapeKind.Square:
            return shape.sideLength ** 2
        }
      }
      
      area(c) // 314.1592653589793
      area(s) // 10000
      

    其他不常用类型

    • null

      let n: null = null
      
    • undefined

      let u: undefined = undefined
      
    • bigint

      bigint 类型是 JavaScript 中的一个新的原始类型,它表示一个无符号整数,可以表示任意大小的整数。

      let bigInt: bigint = 100n
      
    • symbol

      symbol 类型是 JavaScript 中的一个新的原始类型,它表示一个独一无二的值。

      let sym1: symbol = Symbol("key1")
      let sym2: symbol = Symbol("key1")
      sym1 === sym2 // false
      

    如何将 TypeScript 编译为 JavaScript ?

    • 单文件
    1. 全局安装 typescript

      npm i -g typescript
      
    2. 使用 tsc 命令将 TypeScript 文件编译为 JavaScript。

      tsc javascript.js
      
    • Webpack 中使用
    1. 安装 typescript 和 ts-loader

      npm i typescript ts-loader -D
      
    2. 在 webpack.config.js 中配置 ts-loader

      module.exports = {
        module: {
          rules: [
            {
              test: /\.tsx?$/,
              use: "ts-loader",
              exclude: /node_modules/,
            },
          ],
        },
      }
      
    3. 在根目录配置 tsconfig.json,用于指定编译项目所需的根目录下的文件以及编译选项。

      {
        "compilerOptions": {
          "module": "esnext", // 模块类型
          "target": "es5", // 指定编译目标
          "lib": ["esnext"] // 指定引入的库
        },
        "include": ["src/**/*"], // 指定编译的文件
        "exclude": ["node_modules"] // 排除编译的文件
      }
      

      更多配置项参考:https://www.typescriptlang.org/docs/handbook/tsconfig-json.html


    参考资料:

    相关文章

      网友评论

        本文标题:TS:TypeScript 简单入门

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