TypeScript 的基本介绍

229 阅读1分钟
  • 概述

    • 基于 JavaScript 基础之上的编程语言
    • 是一个 JavaScript 的超集
    • TypeScript = JavaScript + 类型系统 + ES6+
    • 任何一种 JavaScript 运行环境都支持
    • 功能更强大,生态更健全,更完善
    • TypeScript 是渐进式的
    • 缺点
      • 语言本身多了很多概念,比如:接口,泛型,枚举
      • 项目初期,TypeScript 会增加一些成本
  • 快速上手

    • 安装 typescript,yarn add typescript --dev

    • 新建 ts 文件

      const hello = (name:string) => {
        console.log(`Hello, ${name}`)
      }
      
      hello('kjy')
      
  • typescript 配置文件

    • 初始化 typescript 配置文件

      • yarn tsc --init

        {
          "compilerOptions": {
            /* Visit https://aka.ms/tsconfig.json to read more about this file */
        
            /* Basic Options */
            // "incremental": true,                   /* Enable incremental compilation */
            "target": "es5",                          /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
            "module": "commonjs",                     /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
            // "lib": [],                             /* Specify library files to be included in the compilation. */
            // "allowJs": true,                       /* Allow javascript files to be compiled. */
            // "checkJs": true,                       /* Report errors in .js files. */
            // "jsx": "preserve",                     /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
            // "declaration": true,                   /* Generates corresponding '.d.ts' file. */
            // "declarationMap": true,                /* Generates a sourcemap for each corresponding '.d.ts' file. */
            "sourceMap": true,                     /* Generates corresponding '.map' file. */
            // "outFile": "./",                       /* Concatenate and emit output to single file. */
            "outDir": "./dist",                        /* Redirect output structure to the directory. */
            "rootDir": "./src",                       /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
            // "composite": true,                     /* Enable project compilation */
            // "tsBuildInfoFile": "./",               /* Specify file to store incremental compilation information */
            // "removeComments": true,                /* Do not emit comments to output. */
            // "noEmit": true,                        /* Do not emit outputs. */
            // "importHelpers": true,                 /* Import emit helpers from 'tslib'. */
            // "downlevelIteration": true,            /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
            // "isolatedModules": true,               /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
        
            /* Strict Type-Checking Options */
            "strict": true,                           /* Enable all strict type-checking options. */
            // "noImplicitAny": true,                 /* Raise error on expressions and declarations with an implied 'any' type. */
            // "strictNullChecks": true,              /* Enable strict null checks. */
            // "strictFunctionTypes": true,           /* Enable strict checking of function types. */
            // "strictBindCallApply": true,           /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
            // "strictPropertyInitialization": true,  /* Enable strict checking of property initialization in classes. */
            // "noImplicitThis": true,                /* Raise error on 'this' expressions with an implied 'any' type. */
            // "alwaysStrict": true,                  /* Parse in strict mode and emit "use strict" for each source file. */
        
            /* Additional Checks */
            // "noUnusedLocals": true,                /* Report errors on unused locals. */
            // "noUnusedParameters": true,            /* Report errors on unused parameters. */
            // "noImplicitReturns": true,             /* Report error when not all code paths in function return a value. */
            // "noFallthroughCasesInSwitch": true,    /* Report errors for fallthrough cases in switch statement. */
        
            /* Module Resolution Options */
            // "moduleResolution": "node",            /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
            // "baseUrl": "./",                       /* Base directory to resolve non-absolute module names. */
            // "paths": {},                           /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
            // "rootDirs": [],                        /* List of root folders whose combined content represents the structure of the project at runtime. */
            // "typeRoots": [],                       /* List of folders to include type definitions from. */
            // "types": [],                           /* Type declaration files to be included in compilation. */
            // "allowSyntheticDefaultImports": true,  /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
            "esModuleInterop": true,                  /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
            // "preserveSymlinks": true,              /* Do not resolve the real path of symlinks. */
            // "allowUmdGlobalAccess": true,          /* Allow accessing UMD globals from modules. */
        
            /* Source Map Options */
            // "sourceRoot": "",                      /* Specify the location where debugger should locate TypeScript files instead of source locations. */
            // "mapRoot": "",                         /* Specify the location where debugger should locate map files instead of generated locations. */
            // "inlineSourceMap": true,               /* Emit a single file with source maps instead of having a separate file. */
            // "inlineSources": true,                 /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
        
            /* Experimental Options */
            // "experimentalDecorators": true,        /* Enables experimental support for ES7 decorators. */
            // "emitDecoratorMetadata": true,         /* Enables experimental support for emitting type metadata for decorators. */
        
            /* Advanced Options */
            "skipLibCheck": true,                     /* Skip type checking of declaration files. */
            "forceConsistentCasingInFileNames": true  /* Disallow inconsistently-cased references to the same file. */
          }
        }
        
  • 原始数据类型

    /**
     * 原始数据类型
     */
    
     const a: string = 'kjy' // string
     const b: number = 100 // number, NaN, Infinity
     const c: boolean = true // true, false
     const d: null = null // null
     const e: void = undefined
     const f: symbol = Symbol()
    
  • 标准库

    • 内置对象所对应的声明
    • 更改 tsconfig.json 中的 lib 属性,lib: ["ES2015", "DOM"]
  • Object 类型

    • object 类型不单指普通的对象

      /**
       * Object 类型
       */
      export {}
      
      const foo:object = {} // function, [], {}
      
      // object 类型不单指普通的对象,是除了原始类型之外的其他类型
      // 如果使用对象类型,可以用对象字面量来标记
      // 复制的对象结果必须和标记的结果必须一致
      const obj: { name: string } = { name: 'kjy' }
      
  • 数组类型

    /**
     * 数组类型
     */
    
    const arr1: Array<number> = [1, 2, 3]
    const arr2: number[] = [1, 2, 3]
    
    function sum(...args: number[]) {
      return args.reduce((prev, current) => prev + current, 0)
    }
    
  • 元组类型

    /**
     * 元组类型
     */
    export {}
    
    const tuple: [number, string] = [100, 'kjy']
    
  • 枚举类型

    • 可以给一组数值分别起上一个更好理解的名字
    • 一个枚举中只会存在几个固定的值,并不会出现超出范围的可能性
    /**
     * 枚举类型
     */
    
    export { }
    
    // const PostStatus = {
    //   Draft: 0,
    //   Unpublished: 1,
    //   Published: 2
    // }
    
    // enum PostStatus {
    //   Draft = 0,
    //   Unpublished = 1,
    //   Published = 2
    // }
    
    // 枚举中的值可以不用赋值,默认会从 0 进行累加,如果给第一个成员设置值,会以第一个成员为标准进行累加
    // 如果值为字符串,必须手动添加值
    enum PostStatus {
      Draft,
      Unpublished,
      Published
    }
    
    const post = {
      title: 'Hello TypeScript',
      content: 'TypeScript is a typed superset of JavaScript',
      status: PostStatus.Draft
    }
    
  • 函数类型

    • 形参和实参必须保证完全一致
    /**
     * 函数类型
     */
    
    export { }
    
    function foo(a: number, b: number): number {
      return a + b
    }
    
    // 可选参数
    function foo1(a: number, b?: number): number {
      return a + b
    }
    
    // 参数默认值
    function foo2(a: number, b: number = 0): number {
      return a + b
    }
    
  • 任意类型

    /**
     * 任意类型
     */
    
    export { }
    
    function stringify(value: any) {
      return JSON.stringify(value)
    }
    
  • 隐式类型断言

    /**
     * 类型断言
     */
    
    export { }
    
    const nums = [100, 200, 300]
    
    const res = nums.find(i => i > 0)
    
    // 使用 as 断言
    const num1 = res as number
    
    // 使用 <> 断言
    // react 中 jsx 会和标签产生冲突
    const num2 = <number>res
    
    const square = num1 * num1
    
  • 接口 interface

    • 可以理解为一种规范或契约

    • 只是为有结构的数据做类型约束,并不会出现在编译后的代码中

      /**
       * 接口
       */
      export { }
      
      interface Post {
        title: string
        content: string
        // 可选
        subtitle?: string
        // 只读
        readonly summary: number
      }
      
      function printPost(post: Post) {
        console.log(post.title)
        console.log(post.content)
      }
      
      // 动态成员
      
      interface Cache {
        [prop: string]: string
      }
      
      const cache: Cache = {}
      
      cache.foo = 'kjy'
      
  • /**
     * 类
     */
    
    export { }
    
    class Person {
      constructor(name: string, age: number, gender: boolean) {
        this.name = name
        this.age = age
        this.gender = gender
        this.content = 'readonly'
      }
      name: string
      // 私有属性,只有在类的内部被访问
      private age: number
      // 受保护的
      protected gender: boolean
      // 只读
      readonly content: string
    
      saiHi(msg: string): void {
        console.log(`hi, ${msg}`)
      }
    }
    
  • 类和接口

    /**
     * 类和接口
     */
    
    export { }
    
    interface Eat {
      eat(food: string): void
    }
    
    interface Run {
      run(distance: string): void
    }
    
    class Animal implements Eat, Run {
      eat(food: string): void {
        console.log(`呼噜呼噜的吃${food}`)
      }
      run(distance: string): void {
        console.log(`跑了${distance}米`)
      }
    }
    
    class Dog implements Eat, Run {
      eat(food: string): void {
        console.log(`呼噜呼噜的吃${food}`)
      }
      run(distance: string): void {
        console.log(`跑了${distance}米`)
      }
    }
    
  • 抽象类

    /**
     * 抽象类
     */
    
    export { }
    
    abstract class Animal {
      eat(food: string): void {
        console.log(`呼噜呼噜的吃${food}`)
      }
    
      abstract run(distance: string): void
    }
    
    class Dog extends Animal {
      run(distance: string): void {
        console.log(`跑了${distance}米`)
      }
    }
    
  • 泛型

    /**
     * 泛型
     */
    
    export { }
    
    // 创建数字数组
    function createNumberArray(length: number, value: number): number[] {
      const arr = Array<number>(length).fill(value)
      return arr
    }
    
    // 创建字符串数组
    function createStringArray(length: number, value: string): string[] {
      const arr = Array<string>(length).fill(value)
      return arr
    }
    
    // 创建通用数组
    function createArray<T>(length: number, value: T): T[] {
      const arr = Array<T>(length).fill(value)
      return arr
    }