如果您想要的只是让编译器捕获参数数量错误的绑定方法,并且您不关心this
上下文,您只需确保启用the --strictBindCallApply编译器选项 https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-2.html#strictbindcallapply:
class StringListeningClassThing {
myString = "hey";
oneParam(x: string) {
return x + this.myString;
}
twoParams(x: number, y: string) {
return x.toFixed(2) + y + this.myString;
}
}
const onPageSizeSelected = new EventTyped<string>();
const stringListenerThingy = new StringListeningClassThing();
onPageSizeSelected.Attach(
stringListenerThingy.twoParams); // error
onPageSizeSelected.Attach(
stringListenerThingy.twoParams.bind(stringListenerThingy)); // error
onPageSizeSelected.Attach(
stringListenerThingy.oneParam.bind(stringListenerThingy)); // okay
onPageSizeSelected.Attach(
stringListenerThingy.twoParams.bind(stringListenerThingy, 2)); // okay
这可能就是您所需要的。但这里仍然存在一些类型安全问题:
不幸的是 TypeScript 在类型检查方面做得并不好this
自动上下文:
onPageSizeSelected.Attach(
stringListenerThingy.oneParam); // no error
onPageSizeSelected.Attach(
stringListenerThingy.oneParam.bind({ notGood: true })); // no error
这些被接受的事实意味着您将遇到运行时错误,如stringListenerThingy
的方法取消引用不好this
.
有一个建议位于微软/TypeScript#7968 https://github.com/Microsoft/TypeScript/issues/7968添加类似的东西--strictThis
编译器选项将阻止您传递错误绑定的函数,但它尚未实现,显然是因为它会两者都会破坏大量现有代码并对编译器性能产生重大影响 https://github.com/Microsoft/TypeScript/issues/7689#issue-143586130。如果您想看到它的实现,您可能需要转到该问题并给它一个????和/或描述您的用例(如果它特别引人注目并且该问题中尚未提及)。
如果你真的想让编译器做这个检查,它is可能,但您需要添加this参数 https://www.typescriptlang.org/docs/handbook/2/classes.html#this-parameters手动到代码中的各种位置。例如,您可以执行以下操作:
// explicitly add void this-context to definition of Listener
export interface Listener<T> {
(this: void, event: T): any;
}
// explicitly add class-based this-context to all methods
class StringListeningClassThing {
myString = "hey";
oneParam(this: StringListeningClassThing, x: string) {
return x + this.myString;
}
twoParams(this: StringListeningClassThing, x: number, y: string) {
return x.toFixed(2) + y + this.myString;
}
}
现在上面的例子给出了所需的错误:
// enjoy type safety
onPageSizeSelected.Attach(
stringListenerThingy.oneParam); // error
onPageSizeSelected.Attach(
stringListenerThingy.oneParam.bind({ notGood: true })); // error
所以编译器can强制执行这些内容,但不会自动执行,直到并且除非--strictThis
成为一件事。
Playground 代码链接 https://www.typescriptlang.org/play?ts=4.5.2#code/PTAEFMA8AcBsEsDG8AusCeoCGATHoA3Ae3nxQAt4BnURIgOxShQFgAoKaIgJxVHkbhuAMyyJwoADLUm9IQB4AKgD5QAb3ahQACgrUAXIRI4ANBALhGhxQEpDWeugDc7AL7t2nHn0SwsVGgBRC0ZFdGhwHCVVDTYtEABBbm4sTCJhUAQqWSEqTVBobngCLCZMmUtcw2lsyu5ogG0AXVAAXlBmlzZ8hJQUMXJtLJzuaoq5epUbdXytPSoAOmG6xegAVypB5YmbLq13brjQQIBbVG1wEJRraditOcpF7dyF4R5AgaHxoTbVZ+4LlcbLt8gcDuwQBAYAhkGhMLh8L5-FQALQAI38kVA8xRdEEkD4KCI2FgsFAJ3AFCIOBo7CRAVAAGUUEV6ABzGqyARsgDCfgCiko7JmRxO6GZrLZbVAACJyOB0DK9qAGOAAApYFInXSPQwS7mcyzcvnIwXcsyQQzZSW3WagbiUtbceigSCgADU2MeCzF+vZyoOcwA7kQNVqqDqDEyWQbxsb+VQzeyLYZ6GsTmihGZ0FaY+zbUctA6UE6XZAFkSAGLwSCRbQAJmmnswnvmPvFebZAbcHjYeOyKvoGrZ4EZ8AAXqPwLBwIgmPh2nIg8crmEIlFrdzlNoQX2GAPN+zDRMk2zMIvwMu-Ry4+yTQKhWyd10IWAUSjN3OAEICHA8rCkgk0BwJg8qwNANDyg67AMMOo4TlOM5zpECy9P0iCDIeN61Cej7oBWIZhlgJxULsoCQkI3A8NgNA4OAVDwA6OAwUOWAjmOk6MtOs7zqhfSfFhx5CKe+EoIRmrEYsaK-tognfNwInAk45FgJR1H+KAdEMUxLFwRxiE8ShaECZ2QkKXhCyqkRJwLNJ9A4LJpnyYpZGQkQADWqQAIS6Wx8GcdxyE4Hx6GYU5OHCRZYmhhJJG2TJckReZ3LoGYjauWAHmpL2FH0AAVkQmAoOEEhUFgwiUpgWi+exCFcUhvHGRh2j5IlIwiZZcjWRlEDJOptH0YxkQ1f5BlBSFnyteF7UWVZsXxfZ2hqKA9BECgADiRDUoYLJrBIrhKSpJJUMSancL2QA