目录:
  1. tsconfig.json配置
    1. 声明空间
      1. 命名空间
        1. 类型系统
          1. 基本类型注释
            1. 数组类型注释
              1. 常见的类型
                1. 对象类型注释
                  1. any、void
                    1. never
                      1. null、undefined
                        1. 联合类型
                          1. 交叉类型
                            1. 类型别名
                              1. 类型推断
                                1. Error类型
                                2. 函数
                                  1. 基本注释
                                    1. 函数重载
                                      1. 泛型
                                        1. 模块
                                          1. 模块动态引入
                                          2. 关键字解释
                                            1. declare
                                              1. implement
                                                1. readonly
                                                  1. typeof
                                                    1. keyof

                                                    TypeScript学习笔记

                                                    阅读时间:全文 2105 字,预估用时 11 分钟
                                                    创作日期:2019-10-10
                                                    文章标签:
                                                     
                                                    BEGIN

                                                    tsconfig.json配置

                                                    {
                                                      "compilerOptions": {
                                                    
                                                        /* 基本选项 */
                                                        "target": "es5",                       // 指定 ECMAScript 目标版本: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'
                                                        "module": "commonjs",                  // 指定使用模块: 'commonjs', 'amd', 'system', 'umd' or 'es2015'
                                                        "lib": [],                             // 指定要包含在编译中的库文件
                                                        "allowJs": true,                       // 允许编译 javascript 文件
                                                        "checkJs": true,                       // 报告 javascript 文件中的错误
                                                        "jsx": "preserve",                     // 指定 jsx 代码的生成: 'preserve', 'react-native', or 'react'
                                                        "declaration": true,                   // 生成相应的 '.d.ts' 文件
                                                        "sourceMap": true,                     // 生成相应的 '.map' 文件
                                                        "outFile": "./",                       // 将输出文件合并为一个文件
                                                        "outDir": "./",                        // 指定输出目录
                                                        "rootDir": "./",                       // 用来控制输出目录结构 --outDir.
                                                        "removeComments": true,                // 删除编译后的所有的注释
                                                        "noEmit": true,                        // 不生成输出文件
                                                        "importHelpers": true,                 // 从 tslib 导入辅助工具函数
                                                        "isolatedModules": true,               // 将每个文件做为单独的模块 (与 'ts.transpileModule' 类似).
                                                    
                                                        /* 严格的类型检查选项 */
                                                        "strict": true,                        // 启用所有严格类型检查选项
                                                        "noImplicitAny": true,                 // 在表达式和声明上有隐含的 any类型时报错
                                                        "strictNullChecks": true,              // 启用严格的 null 检查
                                                        "noImplicitThis": true,                // 当 this 表达式值为 any 类型的时候,生成一个错误
                                                        "alwaysStrict": true,                  // 以严格模式检查每个模块,并在每个文件里加入 'use strict'
                                                    
                                                        /* 额外的检查 */
                                                        "noUnusedLocals": true,                // 有未使用的变量时,抛出错误
                                                        "noUnusedParameters": true,            // 有未使用的参数时,抛出错误
                                                        "noImplicitReturns": true,             // 并不是所有函数里的代码都有返回值时,抛出错误
                                                        "noFallthroughCasesInSwitch": true,    // 报告 switch 语句的 fallthrough 错误。(即,不允许 switch 的 case 语句贯穿)
                                                    
                                                        /* 模块解析选项 */
                                                        "moduleResolution": "node",            // 选择模块解析策略: 'node' (Node.js) or 'classic' (TypeScript pre-1.6)
                                                        "baseUrl": "./",                       // 用于解析非相对模块名称的基目录
                                                        "paths": {},                           // 模块名到基于 baseUrl 的路径映射的列表
                                                        "rootDirs": [],                        // 根文件夹列表,其组合内容表示项目运行时的结构内容
                                                        "typeRoots": [],                       // 包含类型声明的文件列表
                                                        "types": [],                           // 需要包含的类型声明文件名列表
                                                        "allowSyntheticDefaultImports": true,  // 允许从没有设置默认导出的模块中默认导入。
                                                    
                                                        /* Source Map Options */
                                                        "sourceRoot": "./",                    // 指定调试器应该找到 TypeScript 文件而不是源文件的位置
                                                        "mapRoot": "./",                       // 指定调试器应该找到映射文件而不是生成文件的位置
                                                        "inlineSourceMap": true,               // 生成单个 soucemaps 文件,而不是将 sourcemaps 生成不同的文件
                                                        "inlineSources": true,                 // 将代码与 sourcemaps 生成到一个文件中,要求同时设置了 --inlineSourceMap 或 --sourceMap 属性
                                                    
                                                        /* 其他选项 */
                                                        "experimentalDecorators": true,        // 启用装饰器
                                                        "emitDecoratorMetadata": true          // 为装饰器提供元数据的支持
                                                      },
                                                      // 指定编译的文件
                                                      "files": [
                                                        "./some/file.ts"
                                                      ],
                                                      // 包含的文件
                                                      "include": [
                                                        "./folder"
                                                      ],
                                                      // 排除的文件
                                                      "exclude": [
                                                        "./folder/**/*.spec.ts",
                                                        "./folder/someSubFolder"
                                                      ]
                                                    }

                                                    声明空间

                                                    1. 类型声明空间, 关键词如: class、interface、type.
                                                    2. 变量声明空间

                                                    命名空间

                                                    • 原代码:
                                                    namespace Utility {
                                                      export function log(msg) {
                                                        console.log(msg);
                                                      }
                                                      export function error(msg) {
                                                        console.log(msg);
                                                      }
                                                    }
                                                    
                                                    // usage
                                                    Utility.log('Call me');
                                                    Utility.error('maybe');
                                                    • 转义后代码:
                                                    (function (Utility) {
                                                      Utility.log = function msg(msg) {
                                                        console.log(msg);
                                                      }
                                                      Utility.error = function msg(msg) {
                                                        console.log(msg);
                                                      }
                                                    })(Utility || Utility = {});
                                                    
                                                    // usage
                                                    Utility.log('Call me');
                                                    Utility.error('maybe');

                                                    类型系统

                                                    基本类型注释

                                                    • 样句: const num: number = 123;
                                                    • 类型: numberstringboolean

                                                    数组类型注释

                                                    • 同类型数组: const numArr: number[] = [1, 2, 3];等同于const numArr: Array<number> = [1, 2, 3]
                                                    • 不同类型数组: const coor: [string, number]

                                                    常见的类型

                                                    1. Event
                                                    2. MouseEvent
                                                    3. HTMLElement

                                                    对象类型注释

                                                    • 内联方式
                                                    let name: {
                                                      first: string;
                                                      second: string;
                                                    };
                                                    • 接口方式
                                                    interface Name {
                                                      first: string;
                                                      second: string;
                                                      [key: string]: string;
                                                    }
                                                    let name: Name;

                                                    any、void

                                                    1. any类型让typescript关闭类型检测;
                                                    2. void用于函数表示没有返回值.

                                                    never

                                                    当一个函数从不退出和返回或者一直报错, 则可以使用never代替void

                                                    null、undefined

                                                    null和undefined可以赋值给任何类型

                                                    联合类型

                                                    如: const coor: string[] | string;

                                                    交叉类型

                                                    如在函数中传入两个对象, 属性类型不同时, 此时可以使用交叉类型.

                                                    function extend<T, U>(first: T, second: U): T & U {
                                                      const result = <T & U>{};
                                                      for (let id in first) {
                                                        (<T>result)[id] = first[id];
                                                      }
                                                      for (let id in second) {
                                                        if (!result.hasOwnProperty(id)) {
                                                          (<U>result)[id] = second[id];
                                                        }
                                                      }
                                                    
                                                      return result;
                                                    }
                                                    const x = extend({ a: 'hello' }, { b: 42 }); // x值为{ a: 'hello', b: 42 }

                                                    类型别名

                                                    如:

                                                    type Text = string | { text: string };
                                                    type Coordinates = [number, number];
                                                    type Callback = (data: string) => void;

                                                    类型推断

                                                    假设存在接口Foo

                                                    interface Foo {
                                                      bar: number;
                                                      bas: string;
                                                    }
                                                    • 类型推断方式一, 写法会与jsx冲突
                                                    var foo = <Foo> {};
                                                    foo.var = 123;
                                                    foo.bas = 'hello';
                                                    • 类型推断方式二
                                                    var foo = {} as Foo;
                                                    foo.var = 123;
                                                    foo.bas = 'hello';
                                                    • 对应的强制类型转换
                                                    var foo: Foo = {
                                                      var: 123,
                                                      bar: 'hellow'
                                                    };

                                                    Error类型

                                                    1. Error: 基类;
                                                    2. RangeError: 数字范围越界, 如: console.log.apply(console, new Array(1000000000));;
                                                    3. ReferenceError: 使用未经定义的变量时, 如: console.log(notValidVar);;
                                                    4. SyntaxError: 语法错误, 如: 1***3;;
                                                    5. TypeError: 类型错误, 如: ('1.2').toPrecision(1);;
                                                    6. URIError: URI应用错误, 如: decodeURI('%');

                                                    函数

                                                    基本注释

                                                    // 参数注解
                                                    function foo(par1: string) {}
                                                    // 返回类型注解
                                                    function foo(par1: string): number {}
                                                    // 可选参数
                                                    function foo(par1: string, par2?: number): number {}
                                                    // 默认值
                                                    function foo(par1: string, par2: number = 0): number {}

                                                    函数重载

                                                    interface Overloaded {
                                                      (foo: string): string;
                                                      (foo: number): number;
                                                    }
                                                    
                                                    // 实现接口的一个例子:
                                                    function stringOrNumber(foo: number): number;
                                                    function stringOrNumber(foo: string): string;
                                                    function stringOrNumber(foo: any): any {
                                                      if (typeof foo === 'number') {
                                                        return foo * foo;
                                                      } else if (typeof foo === 'string') {
                                                        return `hello ${foo}`;
                                                      }
                                                    }
                                                    
                                                    const overloaded: Overloaded = stringOrNumber;
                                                    
                                                    // 使用
                                                    const str = overloaded(''); // str 被推断为 'string'
                                                    const num = overloaded(123); // num 被推断为 'number'

                                                    什么类属性的方式有: staticpublicprotectedprivate

                                                    其中static表示类对象的属性, 实例化对象及类内部无法引用.

                                                    类型publicprotectedprivatestatic
                                                    classyesyesyesno
                                                    class childrenyesyesnono
                                                    class instancesyesnonono
                                                    • public、protected、private的使用示例
                                                    class FooBase {
                                                      public x: number;
                                                      private y: number;
                                                      protected z: number;
                                                    }
                                                    
                                                    // 类实例化
                                                    var foo = new FooBase();
                                                    foo.x; // okay
                                                    foo.y; // ERROR : private
                                                    foo.z; // ERROR : protected
                                                    
                                                    // 类继承
                                                    class FooChild extends FooBase {
                                                      constructor() {
                                                        super();
                                                        this.x; // okay
                                                        this.y; // ERROR: private
                                                        this.z; // okay
                                                      }
                                                    }
                                                    • static的使用示例
                                                    // typescript代码, 转换前
                                                    class Something {
                                                      static instances = 0;
                                                      constructor() {
                                                        Something.instances++;
                                                      }
                                                    }
                                                    var s1 = new Something();
                                                    var s2 = new Something();
                                                    console.log(Something.instances); // 2
                                                    
                                                    // ecma5代码, 转换后
                                                    var Something = (function () {
                                                      function Something() {
                                                        Something.instances++;
                                                      }
                                                      Something.instances = 0;
                                                      return Something;
                                                    })();
                                                    var s1 = new Something();
                                                    var s2 = new Something();
                                                    console.log(Something.instances); // 2

                                                    泛型

                                                    • 泛型在类中的使用
                                                    class Queue<T> {
                                                      private data = [];
                                                      push(item: T) { this.data.push(item); }
                                                      pop(): T | undefined { return this.data.shift(); }
                                                    }
                                                    
                                                    const queue = new Queue<number>();
                                                    queue.push(0);
                                                    queue.push("1"); // ERROR : cannot push a string. Only numbers allowed
                                                    • 在函数中使用
                                                    function reverse<T>(items: T[]): T[] {
                                                      var toreturn = [];
                                                      for (let i = items.length - 1; i >= 0; i--) {
                                                        toreturn.push(items[i]);
                                                      }
                                                      return toreturn;
                                                    }
                                                    
                                                    var sample = [1, 2, 3];
                                                    var reversed = reverse(sample);
                                                    console.log(reversed); // 3,2,1
                                                    
                                                    reversed[0] = '1';     // Error!
                                                    reversed = ['1', '2']; // Error!
                                                    
                                                    reversed[0] = 1;       // Okay
                                                    reversed = [1, 2];     // Okay
                                                    • 一个很好的示例
                                                    const getJSON = <T>(config: {
                                                      url: string,
                                                      headers?: { [key: string]: string },
                                                    }): Promise<T> => {
                                                      const fetchConfig = ({
                                                        method: 'GET',
                                                        'Accept': 'application/json',
                                                        'Content-Type': 'application/json',
                                                        ...(config.headers || {})
                                                      });
                                                      return fetch(config.url, fetchConfig)
                                                      .then<T>(response => response.json());
                                                    }
                                                    
                                                    type LoadUsersResponse = {
                                                      users: {
                                                        name: string;
                                                        email: string;
                                                      }[];
                                                    }
                                                    function loadUsers() {
                                                      return getJSON<LoadUsersResponse>({ url: 'https://example.com/users' });
                                                    }
                                                    • 泛型用于简单函数
                                                    declare function send<T>(arg: T): void;
                                                    send<number[]>([1, 2]);

                                                    模块

                                                    模块的导入导出方式与ES6的差不多, 当导入接口类型应注意如下区别:

                                                    // typescript, 转换前
                                                    import foo = require('foo');
                                                    var bar: foo;
                                                    // javascript, 转换后
                                                    var bar;
                                                    // typescript, 转换前
                                                    import foo = require('foo');
                                                    var bar = foo;
                                                    // javascript, 转换后
                                                    var foo = require('foo');
                                                    var bar = foo;

                                                    模块动态引入

                                                    import(/* webpackChunkName: "momentjs" */ "moment")
                                                      .then((moment) => {
                                                          // lazyModule has all of the proper types, autocomplete works,
                                                          // type checking works, code references work \o/
                                                          const time = moment().format();
                                                          console.log("TypeScript >= 2.4.0 Dynamic Import Expression:");
                                                          console.log(time);
                                                      })
                                                      .catch((err) => {
                                                          console.log("Failed to load moment", err);
                                                      });

                                                    关键字解释

                                                    declare

                                                    当需要实例化一个变量但又不给它赋值时使用

                                                    implement

                                                    用于类声明继承接口

                                                    interface Point {
                                                        x: number; y: number;
                                                    }
                                                    class MyPoint implements Point {
                                                        x: number; y: number; // Same as Point
                                                    }

                                                    readonly

                                                    标记为只读

                                                    type Foo = {
                                                        readonly bar: number;
                                                        readonly bas: number;
                                                    }
                                                    // Initialization is okay
                                                    let foo: Foo = { bar: 123, bas: 456 };
                                                    // Mutation is not
                                                    foo.bar = 456; // Error: Left-hand side of assignment expression cannot be a constant or a read-only property

                                                    typeof

                                                    获取变量的类型, 将继承被typeof元素的特性, 当为const时, 赋值不可变, 如:

                                                    // typeof的变量是var或者let实例化的
                                                    var foo = 123;
                                                    var bar: typeof foo; // 此时bar为number类型
                                                    bar = 456; // Okay
                                                    bar = '789'; // ERROR: Type `string` is not `assignable` to type `number`
                                                    // typeof的变量是const实例化的
                                                    const foo = 123;
                                                    var bar: typeof foo;
                                                    bar = 123; // Okay
                                                    bar = 789; // ERROR: Type '789' is not assignable to type '123'

                                                    keyof

                                                    获取键名keyof 对象类型, 如和typeof配合使用:

                                                    const colors = {
                                                      red: 'reddish',
                                                      blue: 'bluish'
                                                    }
                                                    type Colors = keyof typeof colors;
                                                    // 等效于
                                                    type Colors = 'red' | 'blue';
                                                    FINISH

                                                    随机文章
                                                    人生倒计时
                                                    default