将函数添加到Object原型并使其可用于所有模块

时间:2017-05-04 18:03:18

标签: javascript typescript

我正在使用Typescript进行一些实验,我正在尝试向Object原型添加一个属性,以便它可用于我所有模块中的所有对象。

这是我到目前为止所做的:

在Common.ts文件中

Object.defineProperty(Object.prototype, 'notNull', {
    value: function(name: string){
        if(this === null || this === undefined){
            throw new Error(`${name} cannot be null nor undefined`);
        }

        return this;
    },
    enumerable: false
});

现在我想在另一个文件中使用它:

module SomeModule{
    class Engine{
        constructor(public horsePower: number, public engineType: string){}
    }

    class Car{
        private _engine: Engine;

        constructor(private engine: Engine){
            //Of course here the compiler complains about notNull not existing
            this._engine = engine.notNull('engine');
        }
    }
}

现在我不知所措,因为我不确定通过在Common.ts中导出带有module.exports的“Object”是否有意义。即使我这样做并将其导入我的其他文件,这似乎也没有做任何事情。

有没有办法实现这样的东西?

谢谢。

1 个答案:

答案 0 :(得分:4)

当您更改Object.prototype时,它会影响运行代码的环境中的所有内容,这就是您通常被avoid extending native types建议的原因。

话虽如此,如果你想走这条路,那么你需要做什么:
正如我所说的,一旦你改变了原型,它就已经在运行时可用了,但是编译器还没有意识到这个改变,所以当你尝试使用这个新方法时它会抱怨。

要解决这个问题,您需要使用global augmentation

declare global {
    interface Object {
        notNull(name: string): this;  
    }
}

修改

正如对此答案的评论所示,此方法仅适用于您使用模块(导入/导出),但如果您不这样做则需要执行此操作:

interface Object {
    notNull(name: string): this;  
}

并将其放在您尝试使用notNull的任何文件中使用的位置,例如在所有ts源文件中引用的.d.ts文件中

第二次编辑

使用您刚刚执行的模块:

export class Engine{
    constructor(public horsePower: number, public engineType: string){}
}

export class Car {
    private _engine: Engine;

    constructor(private engine: Engine){
        //Of course here the compiler complains about notNull not existing
        this._engine = engine.notNull('engine');
    }
}

没有module SomeModule { ... }