i extended function prototype but typescript doesn\'t recognize it.
Function.prototype.proc = function() {
var args, target, v;
var __slice = [].slice;
I am adding this to advise against adding prototypes like the example shown in question since many people view this question. Add it as follows:
interface Function {
proc(...args: any[]): any;
}
Object.defineProperty(Function.prototype, 'proc', { value: function(arg: any[]) {
// Your function body
}});
The reason is if you add it to the prototype directly, it could get enumerated if an instance of that function get's enumerated over. for i in ..
. Now this block could be in a code you do not control (recently happened to me), so it is best to keep your code as safe as possible.
Like this:
declare global {
interface Function {
proc() : any;
}
}
Without 'declare global' it doesn't work.
That's how module augmentation works in recent TypeScript versions. Check out the documentation and scroll down to the Module augmentation
section.
There is a Function interface in the standard typescript lib which declares the members of Function objects. You will need to declare proc as a member of that interface with your own add on like the following:
interface Function {
proc(...args: any[]): any;
}
This interface will need to be referenced from anywhere you intend to use 'proc'.
Just adding that if you're trying to add define something that's already declared, then this is the typesafe way of doing so, that also guards against buggy for in
implementations.
export const augment = <U extends (string|symbol), T extends {[key :string] :any}>(
type :new (...args :any[]) => T,
name :U,
value :U extends string ? T[U] : any
) => {
Object.defineProperty(type.prototype, name, {writable:true, enumerable:false, value});
};
Which can be used to safely polyfill. Example
//IE doesn't have NodeList.forEach()
if (!NodeList.prototype.forEach) {
//this errors, we forgot about index & thisArg!
const broken = function(this :NodeList, func :(node :Node, list :NodeList) => void) {
for (const node of this) {
func(node, this);
}
};
augment(NodeList, 'forEach', broken);
//better!
const fixed = function(this :NodeList, func :(node :Node, index :number, list :NodeList) => void, thisArg :any) {
let index = 0;
for (const node of this) {
func.call(thisArg, node, index++, this);
}
};
augment(NodeList, 'forEach', fixed);
}
Unfortunately it can't typecheck your Symbols due to a limitation in current TS, and it won't yell at you if the string doesn't match any definition for some reason, I'll report the bug after seeing if they're already aware.