美文网首页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