typescript 原型如何在打字稿上扩展?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12766117/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How does prototype extend on typescript?
提问by mizchi
i extended function prototype but typescript doesn't recognize it.
我扩展了函数原型,但打字稿无法识别它。
Function.prototype.proc = function() {
var args, target, v;
var __slice = [].slice;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
target = this;
while (v = args.shift()) {
target = target(v);
}
return target;
};
// generated by coffee-script
var foo: (number) => (string) => number
= (a) => (b) => a * b.length;
console.log(foo.proc("first", "second"))
result: tsc -e
结果:tsc -e
The property 'proc' does not exist on value of type 'Function'
how do i extend this object?
我如何扩展这个对象?
回答by nxn
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:
标准打字稿库中有一个 Function 接口,它声明了 Function 对象的成员。您需要将 proc 声明为该接口的成员,并使用您自己的添加项,如下所示:
interface Function {
proc(...args: any[]): any;
}
This interface will need to be referenced from anywhere you intend to use 'proc'.
需要从您打算使用“proc”的任何地方引用此接口。
回答by gaperton
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 documentationand scroll down to the Module augmentationsection.
这就是最近 TypeScript 版本中模块扩充的工作方式。查看文档并向下滚动到该Module augmentation部分。
回答by Hashbrown
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 inimplementations.
只需补充一点,如果您尝试添加定义已经声明的内容,那么这是一种类型安全的方式,也可以防止错误的for in实现。
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
可用于安全的 polyfill。例子
//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 definitionfor some reason, I'll report the bug after seeing if they're already aware.
不幸的是,由于当前 TS的限制,它无法对您的 Symbols 进行类型检查,并且如果由于某种原因字符串与任何定义不匹配,它也不会对您大喊大叫,我会在查看它们是否已经存在后报告该错误意识到的。
回答by Arijoon
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.
原因是如果你直接将它添加到原型中,如果该函数的实例被枚举,它可能会被枚举。for i in ... 现在这个块可能在你无法控制的代码中(最近发生在我身上),所以最好让你的代码尽可能安全。

