神奇魔法类:使用 createMagicClass 增强你的 JavaScript/Typescript 类
2025年8月17日 11:40
什么是神奇魔法类?
神奇魔法类(Magic Class)是一种特殊的类包装器,它通过createMagicClass
函数创建,能够赋予普通 JavaScript/TypeScript 类超能力。这个工具让你的类既可以作为构造函数使用,又可以作为函数调用来配置选项,大大增强了类的灵活性和可用性。
神奇特性
1. 双重身份
魔法类具有双重身份,可以:
- 作为普通类使用用于继承:
class MyClass extends MagicClass
- 作为函数调用来传入选项用于构建类:
class MyClass extends MagicClass({<options>})
2. 生命周期钩子
提供完整的生命周期钩子,让你能够精确控制实例的创建过程:
-
onBeforeInstance
: 实例创建前触发,可以阻止实例创建或修改类 -
onAfterInstance
: 实例创建后触发,可以对实例进行后处理 -
onErrorInstance
: 实例创建出错时触发,可以进行错误处理
使用示例
基本用法
import { createMagicClass } from "flex-tools/classs";
type UserCreateOptions = {
prefix?: string;
x?: number;
};
// 定义一个普通类
class User {
name: string;
prefix: string = "";
constructor(name: string) {
this.name = name;
this.prefix = getMagicClassOptions<UserCreateOptions>(this)?.prefix!;
}
get title() {
return `${this.prefix}${this.name}`;
}
toString() {
return `${this.constructor.name}<${this.name}>`;
}
}
// 创建魔术类
const MagicUser = createMagicClass<typeof User, UserCreateOptions>(User, {
prefix: "Hi,", // 默认配置
x: 1,
onBeforeInstance: (cls, args, _options) => {},
onAfterInstance: (inst, _options) => {},
});
// 直接作为类使用
class Admin extends MagicUser {}
class Guest extends MagicUser({ x: 2, prefix: "欢迎," }) {}
class Customer extends MagicUser({ prefix: "尊贵的" }) {}
const user = new User("用户");
const admin = new Admin("管理员");
const guest = new Guest("访客");
const customer = new Customer("客户");
高级用法:拦截实例创建
const ValidatedPerson = createMagicClass(Person, {
onBeforeInstance: (cls, args, options) => {
const name = args[0];
// 验证名称
if (!name || name.length < 2) {
throw new Error("Name must be at least 2 characters long");
}
// 可以修改参数
args[0] = name.charAt(0).toUpperCase() + name.slice(1);
// 返回false会阻止实例创建
// 返回一个对象会使用该对象作为实例
// 返回一个类会使用该类创建实例
},
onErrorInstance: (error, cls, options) => {
console.error("Failed to create person:", error.message);
},
});
class SitePerson extends ValidatedPerson {}
// 这将抛出错误,因为名称太短
try {
const invalid = new SitePerson("A");
} catch (e) {
console.log(e.message); // "Name must be at least 2 characters long"
}
// 这将成功,并且名称首字母会被自动大写
const valid = new SitePerson("bob"); // 实际名称将是 "Bob"
获取实例配置
你可以使用getMagicClassOptions
函数获取实例的配置选项:
import { createMagicClass, getMagicClassOptions } from "flex-tools/classs";
const MagicPerson = createMagicClass(Person, { version: "1.0" });
const ConfiguredPerson = MagicPerson({ theme: "dark" });
const person = new ConfiguredPerson("Alice");
const options = getMagicClassOptions(person);
console.log(options); // { version: '1.0', theme: 'dark' }
总结
神奇魔法类通过createMagicClass
函数提供了一种优雅而强大的方式来增强 JavaScript/TypeScript 类的能力。它不仅保留了原始类的所有功能,还添加了配置选项、生命周期钩子和灵活的实例化方式,使你的代码更加灵活、可配置且易于维护。
无论你是构建复杂的 UI 组件、可配置的工具类,还是需要精细控制实例创建过程的系统,神奇魔法类都能为你提供强大而灵活的解决方案。
详见flex-tools。