【发布时间】:2021-12-31 11:50:46
【问题描述】:
我有一个将传递的函数绑定到 HTMLElement 的函数:
global.d.ts:
type tPrimitivRestParams = (number | object | string)[];
type tDefaultVoidFunction = (...params: tPrimitivRestParams) => void;
export default class AwesomeFunctions {
public static addClickCallback(id: HTMLElement, func: tDefaultVoidFunction, scope: object, ...argArray: tPrimitivRestParams): void {
[...] // checks
// eslint-disable-next-line no-null/no-null
element.onclick = func ? func.bind(scope, ...argArray) : null;
}
}
export default class AwesomeClass {
private bindMe(id: string):void {}
private bindMeToo():void {}
private bindMeThree(a:string, b: number, c: object): void {}
private bindMeFour(clazz: SomeClass): void {}
private binder():void {
AwesomeFunctions.addClickCallback(document.getElementById('...'), this.bindMeToo, this); // TS says yes
AwesomeFunctions.addClickCallback(document.getElementById('...'), this.bindMe, this, 'param'); // TS says no
AwesomeFunctions.addClickCallback(document.getElementById('...'), this.bindMeThree, this, 'param', 2, {whoopi: 'goldberg', age: 24, 'actual-age': 'dontcha dare askn!!!'}); // TS says no
AwesomeFunctions.addClickCallback(document.getElementById('...'), this.bindMeThree, this, new SomeClass()); // TS says no
}
}
它在 JS 上运行良好,但 TS 大喊大叫,但第一个除外:
// Example for bindMe
S2345: Argument of type '(id: string) => void' is not assignable to parameter of type 'tDefaultVoidFunction'.
如果我这样做:
AwesomeFunctions.addClickCallback(..., this.bindMe as tDefaultVoidFunction , ...);
TS 很满意,但我觉得不对。
我知道这是 tDefaultVoidFunction 类型的问题。是否可以定义一种类型以使 TS 对所有绑定感到满意?我不能使用任何、null 或 Function。
附加问题:
我也可以这样做:
AwesomeFunctions.addClickCallback(..., () => this.bindMe('param'), this);
TS 也很满意,但 95% 的 addClickCallback 函数变得毫无意义。但这不是我犹豫使用箭头函数的原因。我担心范围可能会有所不同。据我所知,范围始终是 this。所以在这种情况下,我声称箭头功能和绑定行为相同。我错了吗?
可重现的例子:
type tPrimitivRestParams = (number | object | string)[];
type tDefaultVoidFunction = (...params: tPrimitivRestParams) => void;
class AwesomeFunctions {
public static addClickCallback(id: string, func: tDefaultVoidFunction, scope: object, ...argArray: tPrimitivRestParams): void {
// DO something
}
}
class AwesomeClass {
private bindMe(id: string):void {}
private bindMeToo():void {}
private bindMeThree(a:string, b: number, c: object): void {}
private binder():void {
AwesomeFunctions.addClickCallback('A', this.bindMeToo, this);
AwesomeFunctions.addClickCallback('B', this.bindMe, this, 'param');
AwesomeFunctions.addClickCallback('C', this.bindMeThree, this, 'param', 2, {whoopi: 'goldberg', age: 24, 'actual-age': 'dontcha dare askn!!!'});
}
}
游乐场:TS Example
【问题讨论】:
-
请提供可重现的例子
-
@captain-yossarian 完成
标签: typescript typescript-types