首页 > 解决方案 > 打字稿如何声明一个返回它被调用的对象的方法(this)

问题描述

如何为on函数编写声明。on函数必须根据调用它的对象返回一个动态类型。

function on(type, handler) {
    this.addEventListener(arguments);

    return this;
}

var element = document.getElementById('elm');
var request = new XMLHttpRequest();

element.on = on; // => element.on(t,cb) must return element 
request.on = on; // => request.on(t,cb) must return request 

这是我的 d.ts(这只是示例,ThisType 不正确)

declare function on<K extends keyof WindowEventMap>(type: string, handler: 
(this: ThisType, ev: WindowEventMap[K]) => any): ThisType;

不知道 Typescript 是否还有其他关键字可以解决这个问题。(这个来电者

标签: javascripttypescript

解决方案


TypeScript 有一个称为多态的特性,这种类型可以在这里使用。

然而,这个任务

element.on = on;

将被标记为错误,因为在 TypeScript 中,您不能仅通过分配给该属性来向对象添加任意属性。

您可以通过添加一个函数来以类型安全的方式执行此操作,该函数将向对象添加on属性,并返回相同的对象,但以适当的类型声明,告诉编译器它现在具有该on属性:

interface EventListeners {
    addEventListener(type: string, handler: () => void): void;
};

function on<T extends EventListeners>(this: T, type: string, handler: () => void): T {
    this.addEventListener(type, handler);

    return this;
}


var element = document.getElementById('elm');
var request = new XMLHttpRequest();

// had to declare this interface in order to use this as return type
interface EventListenersExt extends EventListeners {
    on(type: string, handler: () => void): this;
}
function addOn<T extends EventListeners>(t: T): T & EventListenersExt {
    return Object.assign(t, { on });
}

const elementExt = addOn(element); 
const requestExt = addOn(request);

const e = elementExt.on('click', () => { }).on('keyup', () => { }); // const e: HTMLElement & EventListenersExt
const r = requestExt.on('load', () => { }); // const r: XMLHttpRequest & EventListenersExt  

推荐阅读