很好奇sequelize里面的STRING怎么实现的?

好奇sequelize里面的STRING怎么实现的,既可以DataTypes.STRING当常量用作VARCHAR(255),也可以DataTypes.STRING(32)当做函数用,传参控制VARCHAR长度,看了git项目,里面的STRING只是个class继承了别的class,代码也都没啥新奇的,常量用能理解,函数没看懂,怎么做到既可以是常量也可以是函数的,里面的toString是什么机制调用的

自己想写个类似的

class STRING {
    constructor(len) {
        this.len = len;
    }

    toString() {
        return this.len ? `VARCHAR(${this.len})` : 'VARCHAR(255)';
    }

    get result() {
        return this.len ? `VARCHAR(${this.len})` : 'VARCHAR(255)';
    }
}

写的不对,帮忙看看?

阅读 1.5k
1 个回答

琢磨出来了,直接上代码:

class STRING {
    private len: number;

    constructor(length: number) {
        this.len = length;
    }

    public toString() {
        return `VARCHAR(${this.len})`;
    }

    static toString() {
        return 'VARCHAR(255)';
    }
}

interface StringTypeConstructor {
    new(length: number): STRING;
    (length: number): STRING;
}

const DataTypes = {
    STRING: STRING as StringTypeConstructor
}

DataTypes.STRING = new Proxy(DataTypes.STRING, {
    apply(_target, _thisArg, args) {
        // @ts-ignore
        return new DataTypes.STRING(...args);
    }
});

console.log(DataTypes.STRING.toString());
// VARCHAR(255)
console.log(DataTypes.STRING(123).toString());
// VARCHAR(123)

原理很简单,static属性的toString可以支持DataTypes.STRING的写法,使用Proxy对DataTypes.STRING做代理,代理的内容就是将DataTypes.STRINGnew一下,使其可以接受传参,public属性的toString可以支持代理之后DataTypes.STRING(123)的写法。程序内部取STRING值的时候全部转换为string类型,因为sql拼接的时候无疑是字符串拼接,所以STRING两个toString都派上了用场

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题