美文网首页Typescript
TypeScript学习笔记(三)- 类型检查、高级类型、命名空

TypeScript学习笔记(三)- 类型检查、高级类型、命名空

作者: 景阳冈大虫在此 | 来源:发表于2021-04-27 16:47 被阅读0次

    类型检查

    类型兼容性

    x、y属性一样,多的那个类型可以被赋值给少的那个

    interface x {
      a: number;
      b: number;
    }
    interface y {
      a: number;
      b: number;
      c: number;
    }
    
    let aobj: x = { a: 1, b: 2 };
    let bobj: y = { a: 1, b: 2, c: 3 };
    
    aobj = { a: 1, b: 2, c: 3 };// 不可以
    aobj = bobj; // 可以
    bobj = aobj;// 不可以
    

    函数兼容性

    type Handler = (a:number,b:number) => void;
    
    function task(params: Handler) {
      return params;
    }
    

    入参为基础数据类型

    1. 入参多的可以兼容入参少的
    2. 返回值是对象,属性少的可以兼容属性多的
    3. 可选参数与剩余参数
    type Handler1 = (a: number, b: number) => void;// 固定参数
    type Handler2 = (a?: number, b?: number) => void;// 可选参数
    type Handler3 = (...rest: number[]) => void;// 剩余参数
    let h1: Handler1 = (a: number, b: number) => { };
    let h2: Handler2 = (a?: number, b?: number) => { };
    let h3: Handler3 = (...rest: number[]) => { };
    h1 = h2 = h3;
    
    • 剩余参数视为无限多参数,由于第1条成立,所以剩余参数可以兼容固定参数和可选参数
      修改
    "strictFunctionTypes": false, 
    
    • 剩余参数可以兼容固定参数和可选参数
    • 可选参数可以兼容固定参数和可选参数

    入参为对象

    • 对象属性多的可以兼容对象属性少的;可以理解为入参多的可以兼容入参少的。
    interface Point2D{
      x: number;
      y: number;
    }
    
    interface Point3D{
      x: number;
      y: number;
      z: number;
    }
    
    let p2d=(point: Point2D) => { };
    let p3d = (point: Point3D) => { };
    
    p2d = p3d;// 不可以  修改"strictFunctionTypes": false,  可以
    p3d = p2d;// 可以
    

    返回值类型

    • 返回为对象,则属性少的兼容属性多的

    枚举兼容性

    enum Fruit {
      Apple = 2,
      Banana = 3
    }
    let a: number = Fruit.Apple;// 可以
    Fruit.Apple = Fruit.Banana;// 不可以
    

    类兼容

    class A {
      state: number;
      constructor(val: number) {
        this.state = val;
      }
      run(): number {
        return this.state;
      }
    }
    
    class B {
      state: number;
      static id: number;
      constructor(val: string) {
      }
      run(): number {
        return this.state;
      }
      walk(): number {
        return;
      }
    }
    
    let a = new A(1);
    let b = new B('b');
    a = b;// 可以
    b = a;// 不可以
    
    • 静态成员和构造函数不参与比较
    • 类的私有成员和受保护成员,只允许子类赋值给父类

    泛型兼容

    interface A<T>{
      data: T;
    }
    let x: A<number>;
    let y: A<string>;
    x = y;  // T被使用时不可以,不被使用时可以
    
    • 没有指定类型兼容时,T视为any

    高级类型

    交叉类型

    interface A {
      run(): void;
    }
    interface B {
      walk(): void;
    }
    let c: A & B = {
      run() { },
      walk() { }
    }
    

    联合类型

    let x: string | number;
    let y: 'a' | 'b' | 'c';
    let z = 1 | 2 | 3 | 4;
    
    interface Square {
      kind: "square";
      size: number;
    }
    
    interface Rectangle {
      kind: 'rectangle';
      width: number;
      height: number;
    }
    
    type Shape = Square | Rectangle;
    function area(s: Shape) {
      switch (s.kind) {
        case "square":
          return s.size * s.size;
        case "rectangle":
          return s.height * s.width;
        default:
          return ((e: never) => { throw new Error(e) })(s)  
            // 约束在type而不给case处理的情况,即强制要求每一个type都必须处理
      }
    }
    

    索引类型

    // keyof T
    interface Obj {
      a: number,
      b: string
    }
    let key: keyof Obj;
    
    // T[K]
    let value: Obj['a']
    
    // T extends U
    function getValue<T, K extends keyof T>(obj: T, keys: K[]): T[K][] {
      return keys.map(key => obj[key]);
    }
    

    映射类型

    interface Obj {
      a: string;
      b: string;
      c: number;
    }
    
    // 同态
    // 把所有类型变成只读的
    type ReadonlyObj = Readonly<Obj>;
    // 把所有类型变成可选的
    type PartialObj = Partial<Obj>;
    // 限定选取范围
    type PickObj = Pick<Obj, 'a' | 'b'>;
    
    // 非同态:会创建新的属性
    // x,y属性都是Obj类型
    type RecordObj = Record<'x' | 'y', Obj>;
    let obj: RecordObj = {
      x: {
        a: 'a',
        b: 'b',
        c: 1
      },
      y: {
        a: 'a',
        b: 'b',
        c: 1
      }
    }
    

    namespace

    • 使用export将function导出
    namespace Square{
      let a = 1;
      let b = 2;
      export function task() {
        return a + b;
      }
    }
    
    Square.task();
    
    编译

    合并

    • 两个文件有同名的命名空间,则命名空间会发生合并,但不能有同名export的东西;
    • 与函数合并
      命名空间声明需要放在后面。
    function Lib() { }
    namespace Lib {
      export let version = '1.0';
    }
    console.log(Lib.version);// 1.0
    
    • 与类合并
      命名空间声明需要放在后面。
    class C { }
    namespace C {
      export let state = 1;
    }
    console.log(C.state);// 1
    

    state为class C的静态成员

    • 与enum合并
      命名空间声明可以不放在后面。
    enum Color {
      Red,
      Yellow,
      Bule
    }
    namespace Color {
      export function mix() { }
    }
    console.log(Color);
    

    相关文章

      网友评论

        本文标题:TypeScript学习笔记(三)- 类型检查、高级类型、命名空

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