/** * 定义类,并且把方法混入类的原型中 * 用以实现把类的方法实现和类的定义分离,方法可以实现在其他文件中 * * @example * * ```ts * import {speak} from './sub/speak'; * import {fly} from './sub/fly'; * let Animal = defineClass( * class Animal { constructor(public name: string) {}}, * { speak, fly } * ); * ``` * * @param classBase 基类构造函数 * @param methods 要混入的方法对象 * @returns 混合后的类构造函数 */ export function defineClass>( classBase: TBase, methods: TMethods ): { new (...args: ConstructorParameters): Expand & TMethods> } & TBase { // 创建一个继承自 classBase 的新类 // Create a new class extending classBase // 使用计算属性名来保留原始类名 const name = classBase.name const MixedClass = { [name]: class extends (classBase as any) {}, }[name] // 将方法混合到原型上 // Mix methods into the prototype if (methods) { Object.assign(MixedClass.prototype, methods) } return MixedClass as any } export type Constructor = new (...args: any[]) => T /** * 展开类型,用于优化类型提示 * Expand type for better type hints */ type Expand = T extends infer O ? { [K in keyof O]: O[K] } : never