首要:答案很可能就在那里,但是我不知道它的名字,所以我很遗憾找不到它。
那没关系;我的问题是我想在打字稿中编辑函数的属性(声明它们是因为未声明它们,所以对其进行了声明),但不知道该怎么做。
您只需使用JavaScript即可:
console.log('logError00 ==============================');
logError00('Foo');
logError00('Bar');
logError00('hey');
function logError00(error) {
const _this = logError00;
if(_this.counter === undefined) _this.counter = 1;
else _this.counter++;
console.log(`${_this.counter} | ${error}`);
}
或(这可能不明智,因为它需要在函数调用之前声明):
logError01.counter = 0;
function logError01(error) {
const _this = logError01;
_this.counter++;
console.log(`${_this.counter} | ${error}`);
}
console.log('logError01 ==============================');
logError01('Foo');
logError01('Bar');
logError01('hey');
最后,我想做的是创建一个Class,该类跟踪方法调用的平均次数,而无需声明变量,例如:
class MyClass {
private func1Count = 0;
private func2Count = 0;
[...]
}
这就是我在JS中工作的方式:
class MyError {
constructor(message) {
this.log.counter = 0;
this.message = message;
}
log() {
this.log.counter++;
console.log(`${this.log.counter} | ${this.message}`);
}
}
console.log('MyError (class) ==============================');
const myError = new MyError('Some Message');
myError.log();
myError.log();
myError.log();
这就是我要阻止的内容,但是可以正常编译:
wouldBeMeh('Foo');
wouldBeMeh('Bar');
wouldBeMeh('Hey!');
function wouldBeMeh(error: string) {
const _this = (wouldBeMeh as any);
if(_this.counter === undefined) _this.counter = 1;
else _this.counter++;
console.log(`${_this.counter} | ${error}`);
}
谢谢。
答案 0 :(得分:1)
对于某项功能,它仅适用。使用Typescript,您可以将成员添加到当前作用域中的函数中:
wouldBeMeh.counter = 0;
function wouldBeMeh(error: string) {
if(wouldBeMeh.counter === undefined) wouldBeMeh.counter = 1;
else wouldBeMeh.counter++;
console.log(`${wouldBeMeh.counter} | ${error}`);
}
wouldBeMeh('Foo');
wouldBeMeh('Bar');
wouldBeMeh('Hey!');
答案 1 :(得分:1)
您说您不想声明诸如func1Count
之类的成员变量,但这确实是某人执行此类操作的最直接方法,特别是因为它使用TypeScript编译器的属性和方法了解。如果您可以解释为什么,您不想使用成员变量,则可能有人可以提出一种满足您需要的实现,而不必花太多的时间。
现在,我假设您确实需要向方法中添加属性(而不是独立函数,在TS3.1中添加了support for which)。 TypeScript通常不允许expando属性;如果要向某事物添加属性,则需要知道其类型以具有该属性。
对于无法通过对象文字创建的类似函数的操作,最简单的方法是使用Object.assign()
。形式的东西
const funcWithProp = Object.assign(function(){}, {prop: ""});
将被推断为具有类型
// const funcWithProp: (() => void) & { prop: string; }
既可以用作函数,也可以用作prop
键控对象:
funcWithProp(); // okay
funcWithProp.prop = "hey" // okay
所以,让我们看一下您的课程,看看该怎么做:
我不确定您是否想拥有一个计数器,该计数器在MyError
的任何实例调用其log()
方法时是否递增,或者是否需要单独的计数器? MyError
的每个实例的计数器。所以我会同时实现。
如果您想要一个计数器,则应这样操作:
class MyError {
message: string;
constructor(message: string) {
this.message = message;
}
}
interface MyError {
log: ((this: MyError) => void) & { counter: number };
}
MyError.prototype.log = Object.assign(
function(this: MyError) {
this.log.counter++;
console.log(`${this.log.counter} | ${this.message}`);
},
{ counter: 0 }
);
请注意,我必须使用declaration merging并直接在log
上设置MyError.prototype
。方法通常以原型出现(每个类只有一个),并且当您在class
中声明一个方法时,无法注释您希望它具有更多的属性。因此,正确的注释需要放入interface MyError
内,该注释将合并到class
中,并且实际的实现将分配给MyError.prototype.log
并使用Object.assign()
。还要注意,log
函数签名具有this
parameter。那只是类型系统的一部分,它使编译器知道您只能在MyError
类型的对象上作为方法调用该函数,并且该函数的实现可以访问{{1} }作为this
的实例。
让我们看看它是否有效:
MyError
看起来不错。
如果您希望每个const myError = new MyError("Some Message");
myError.log(); // 1 | Some Message
const myError2 = new MyError("Other Message");
myError.log(); // 2 | Some Message
myError2.log(); // 3 | Other Message
myError.log(); // 4 | Some Message
实例都有自己的日志计数器,该怎么办?我们可以这样:
MyError
现在,我们不能使用原型上使用的常规方法,否则整个class MyError {
message: string;
constructor(message: string) {
this.message = message;
}
log = Object.assign(
function(this: MyError) {
this.log.counter++;
console.log(`${this.log.counter} | ${this.message}`);
},
{ counter: 0 }
);
}
类中只有一个。您想跟踪每个实例对MyError
的调用,这意味着每个实例需要单独的log()
属性。但是,只有在每个实例都有单独的counter
实现时,您才能这样做(好吧,除非您使用log()
成员变量,但您不想这样做)。因此,我们不是将MyError
用作方法,而是使它成为函数值实例属性,并使用log
进行了初始化。我们使用与之前相同的=
代码,并且可以正常工作。
好吧,让我们看看它是否有效:
Object.assign(...)
看起来不错。
好的,希望能有所帮助;祝你好运!