typescript 声明文件 Mixins混入

43 阅读2分钟

声明文件 declare:当使用第三方库时,我们需要引用它的声明文件才能获取相应的代码补全、接口提示等功能

declare var a: number; //声明全局变量
declare function add(params: number) {}; //声明全局方法
declare class A {} //声明全局类
declare enum B { //声明全局枚举
  a,
  b,
  c,
}
declare namespace A {
  //声明全局命名空间
  export const a = 1;
}
declare interface C {
  //声明全局类型
  name: string;
}
declare type D = {
  //声明全局类型
  age: number;
};
//三斜线指令类似于import
<reference path="..." />//用于指定当前文件依赖的其他文件路径。这通常用于引入声明文件,以便在当前文件中使用对应的类型或接口。

<reference types="..." />//用于引入全局声明文件。这个指令告诉编译器查找名为 @types 的文件夹中的声明文件。

<reference lib="..." />//用于引入 TypeScript 标准库的声明文件。可以使用这个指令来指定要包含的 TypeScript 标准库的版本。

//简单手写
declare module 'express' {
    interface Router {
        get(path: string, cb: (req: any, res: any) => void): void
    }
    interface App {
 
        use(path: string, router: any): void
        listen(port: number, cb?: () => void): void
    }
    interface Express {
        (): App
        Router(): Router
 
    }
    const express: Express
    export default express
}

Mixins混入:其实可以把它看作合并

对象混入 A对象 B对象 合并到一起

//对象混入 A对象 B对象 合并到一起
interface A {
  name: string;
}
interface B {
  age: number;
}
let a: A = {
  name: "张三",
};
let b: B = {
  age: 15,
};
//扩展运算符 浅拷贝(第一层属性脱离引用,其他不会) 返回新类型 { age: number;name: string;}
let c = { ...a, ...b };
//Object.assign 浅拷贝 交叉类型A & B
let c2 = Object.assign({}, a, b);

插件类型混入

class Logger {
  log(message: string) {
    console.log(message);
  }
}
class Html {
  render() {
    console.log("render");
  }
}
class App {
  run() {
    console.log("run");
  }
}
type Custructor<T> = new (...args: any[]) => T;
function pluginMixins<T extends Custructor<App>>(Base: T) {
  return class extends Base {
    private Logger: any;
    private Html: any;
    constructor(...args: any[]) {
      super(...args);
      this.Logger = new Logger();
      this.Html = new Html();
    }
    run() {
      this.Logger.log("run");
    }
  };
}
const mixins = pluginMixins(App);
const app = new mixins();
app.run();