美文网首页
TypeScript语言规范与基本应用

TypeScript语言规范与基本应用

作者: 翔子丶 | 来源:发表于2021-01-12 15:27 被阅读0次

    TypeScript解决JavaScript类型系统的问题吗,大大提高代码的可靠程度

    TypeScript是JavaScript的超集(扩展JavaScript语法,提供更强大的类型系统),会被编译为JavaScript类型

    缺点:

    1. 语言本身多了很多概念,增强学习成本(TypeScript属于渐进式)
    2. 项目初期,TypeScript会增加一些成本(长久来说很重要)
    TypeScript安装
    1. yarn init --yes初始化项目
    2. yarn add typeScript --dev 作为开发依赖,此时node_modules/.bin/tsc文件用于编译typeScript
    3. yarn tsc xxx.ts 进行编译
    4. yarn tsc --init生成.tsconfig.json文件
    5. 按需修改配置文件(rootDir为ts文件目录,outDir为输出js文件目录)
    6. 此时直接使用yarn tsc就可进行指定目录编译
    TypeScript使用指南
    • 原始类型

      const a: string = 'foobar'
      const b: number = 100 // NaN Infinity
      const c: boolean = true // false
      // 在非严格模式(strictNullChecks)下,
      // string, number, boolean 都可以为空
      // const d: string = null
      // const d: number = null
      // const d: boolean = null
      const e: void = undefined
      const f: null = null
      const g: undefined = undefined
      // Symbol 是 ES2015 标准中定义的成员,
      // 使用它的前提是必须确保有对应的 ES2015 标准库引用
      // 也就是 tsconfig.json 中的 lib 选项必须包含 ES2015
      const h: symbol = Symbol()
      // Promise
      // const error: string = 100
      
    • 作用域问题

      // a.js
      const a: string = 'a' // 默认文件中的成员会作为全局成员
      // b.js
      const a: number = 2 // 无法重新声明块范围变量“a”。
      // 解决
      // 1.立即执行函数
      (function() {
          const a: number  = 2
      })()
      // 2.使用export 把当前文件变为模块
      const a: number = 2
      export {}
      
    • Object类型

      // 指所有非原始类型
      const foo: object = function() {}
      // 普通对象类型实现 更专业的使用接口类型实现
      const obj: { foo: number, bar: string } = { foo: 123, bar: 'a' }
      
    • 数组类型

      // 两种定义方式
      const arr: number[] = [1,2,3]
      const arr: Array<number> = [1,2,3]
      
      function sum(...args: number[]) {
          // 如果是 JS,需要判断是不是每个成员都是数字
        return args.reduce((prev, current) => prev + current)
      }
      sum(1,2,3)
      
    • 元组类型

      // 明确元素数量以及每个元素类型的数组
      const tuple: [number, string] = [12, 'wang']
      const [age, name] = tuple
      // 编译为js后实际相当于以下代码
      // const age = tuple[0]
      // const name = tuple[1]
      // Object.entries获取到每个键值对就是元组 固定长度 固定类型
      const entries: [string, number][] = Object.entries({
        foo: 123,
        bar: 456
      })
      const [key, value] = entries[0]
      
    • 枚举类型

      // 对象模拟实现枚举
      const PostStatus = {
        Draft: 0,
        Unpublished: 1,
        Published: 2
      }
      enum PostStatus {
        Draft, // 不设置值时默认从0开始递增 相当于Draft = 0,Unpublished = 1,Published = 2
        Unpublished,
        Published
      }
      enum PostStatus {
        Draft = 6, // 相当于Draft = 6,Unpublished = 7,Published = 8
        Unpublished,
        Published
      }
      // 常量枚举,不会侵入编译结果
      const enum PostStatus {
        Draft,
        Unpublished,
        Published
      }
      
    • 函数类型

      // 函数声明
      // 输入输出类型限制
      function fun1(a: number, b: number): string {
        return 'fun1'
      }
      fun1(1, 2)
      // 如果一个参数可有可无
      function fun1(a: number, b?: number): string {
        return 'fun1'
      }
      function fun1(a: number, b: number = 2): string {
        return 'fun1'
      }
      // 如果需要传入多个参数
      function fun1(a: number, b: number = 2, ...rest: number[]): string {
        return 'fun1'
      } 
      // 函数表达式
      const fun2: (a: number, b: number) => string = function (a: number,b: number): string {
        return 'fun2'
      }
      
    • 任意类型

      function stringify(value: any) {
        return JSON.stringify(value)
      }
      stringify('string')
      stringify(100)
      stringify(true)
      
      let foo: any = 'string'
      foo = 100
      foo.bar()
      // any时类型不安全的
      
    • 联合类型

      // 联合类型 通过|将变量设置为多种值
      let strOrNum: string | number = 2
      strOrNum = 'sdf'
      
      let arr: string[] | number[]
      arr = [1, 2, 3]
      arr = ['foo', 'bar', 'baz']
      // 函数参数
      function add(name: string | string[]): void { }
      
    • 隐式类型推断

      let age = 12
      // typeScript推断此类型为number
      age = 'string' // 不能将类型“string”分配给类型“number”
      // 尽可能给每个变量添加类型
      
    • 类型断言

      const nums = [12, 13, 14]
      const res = nums.find(i => i > 0)
      // 类型断言
      const num1 = res as number
      // const num1 = <number>res // JSX下不能使用
      const square = res * res
      
    • 接口

      // 规范或契约 约定一个对象的结构
      interface Post {
        title: string
          content: string
          subtitle?: string // 可选成员
          readonly summary: string // 只读成员
      }
      function printPost(post: Post) {
          console.log(post.title)
          console.log(post.content)
      }
      printPost({
          title: 'hello',
          content: 'China'
      })
      // 动态对象 定义时无法知道有哪些具体成员
      interface Cache {
        [prop: string]: string
      }
      const cache: Cache = {}
      cache.foo = 'value1'
      cache.bar = 'value2'
      
    • 类的基本使用

      // 描述一类具体事物的抽象特征
      // ES6之前,通过函数 + 原型模拟实现类
      // TypeScript增强了class的相关语法
      // 访问修饰符 private私有属性 只能在当前访问 public共有属性 protected只能在继承的子类中访问 相比于private允许继承
      // readonly 只读属性 不能被修改
      class Person {
          public name:string
          private age: number
          protected readonly gender: boolean
          constructor (name: string, age: numberr) {
              this.name = name
              this.age = age
          }
        sayHi (msg: string): void {
            console.log(`I am ${this.name}, ${msg}`)
          }
      }
      
    • TypeScript类与接口

      // 使用接口明确强制一个类去符合某种契约
      // 接口描述类的公共部分
      // 一个接口尽量只定义一个方法
      interface Eat {
        eat(food: string):void
      }
      interface Run {
        run(distance: number): void
      }
      class Animal implements Eat, Run {
        eat(food: string): void {
            console.log(`大口吃:${food}`)
        }
        run(distance: number): void {
          console.log(`爬行:${distance}`)
        }
      }
      class Person implements Eat, Run {
        eat(food: string): void {
          console.log(`细嚼慢咽的吃:${food}`)
        }
        run(distance: number): void {
          console.log(`行走:${distance}`)
        }
      }
      
    • 抽象类

      // abstract修饰 只能被继承 不能使用new创建实例
      // 有抽象方法的类必须被声明为抽象类
      // 和接口相似 抽象方法也是定义但不实现 相比接口 抽象类可以包含成员的实现细节
      abstract class Animal {
        eat(food: string): void {
            console.log(`大口吃:${food}`)
          }
        abstract run(distance: number): void // 抽象方法 不包含具体实现 须在派生类中实现
      }
      class Dog extends Animal {
        run(distance: number): void {
            console.log('四脚爬行', distance)
          }
      }
      
      const d = new Dog()
      d.eat('嗯西马')
      d.run(100)
      
    • 泛型

      // 声明时不指定类型 调用时在指定类型
      // 使用泛型创建可重用的组件
      function createStringArray (length: number, value: string): string[] {
        return Array<string>(length).fill(value)
      }
      function createNumberArray(length: number, value: number): number[] {
        return Array<number>(length).fill(value)
      }
      const res = createStringArray(4, 'ff')
      console.log(res);
      const res1 = createNumberArray(4, 100)
      console.log(res1);
      // 使用泛型的方式
      function createArray<T>(length: number, value: T): T[] {
        return Array<T>(length).fill(value)
      }
      const res2 = createArray<string>(3, 'foo')
      const res3 = createArray<number>(3, 45)
      console.log(res2);
      console.log(res3);
      
    • 类型声明

      ​ 第三方npm模块 这些npm模块不一定通过typeScript编写 无法使用TypeScript类型检查等功能;需将库里的函数和方法体去掉只保留导出类型声明,产出一个描述JavaScript库和模块信息的声明文件,引入此声明文件 就可以借用TypeScript的各种特性来使用库文件

      • 引入模块对应的类型声明模块@types/xx

        // 安装lodash的类型声明模块就可正常使用 yarn add @types/lodash --dev
        import { camelCase } from 'lodash'
        const res = camelCase('hello typed')
        
    image-20210112145412070.png
    • 内部已集成类型声明文件

      // 内部已经继承了类型声明文件 所以不用在声明
      import qs from 'query-string'
      qs.parse('?key=value&key2=value2')
      
    • 如果没有类型声明模块时,自定义declare 关键字来定义类型

      // 以$符号为例
      // 需要使用declare关键字来定义它的类型 帮助TypeScript判断我们传入的参数类型
      declare const $: (selector: string) => any
      $('#foo')
      

    相关文章

      网友评论

          本文标题:TypeScript语言规范与基本应用

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