如何为ES6 ButtonMixin编写正确的TypeScript类型定义以支持智能提示?
正确声明JavaScript混入的TypeScript类型定义
原JavaScript库代码
class Image { constructor() { this.isImage = true; } } class Text { constructor() { this.isText = true; } } const ButtonMixin = Superclass => ( class Button extends Superclass { constructor() { super(); this.isButton = true; } } );
问题场景
需要为上述代码编写TypeScript的.d.ts定义文件,重点是正确声明ButtonMixin函数,让使用者在WebStorm/VSCode中获得准确的智能提示:
- 实例化混入后的类时,能提示基类属性+
isButton - 继承混入后的类创建自定义类时,能提示基类属性+
isButton+自定义属性
错误尝试分析
之前的声明declare function ButtonMixin<T>(baseClass: T): Button & T;无法生效,因为:
T被推断为类的构造函数类型,和抽象类Button交叉后,TypeScript无法正确识别实例属性的合并关系- 返回类型没有明确表示是继承自基类的构造函数,导致
extends操作和实例属性提示异常
正确的类型定义方案
declare class Image { isImage: boolean; } declare class Text { isText: boolean; } // 定义通用构造函数类型,描述类的构造器签名 type Constructor<T = {}> = new (...args: any[]) => T; // 声明ButtonMixin:接收基类构造器,返回继承该基类且添加isButton属性的新构造器 declare function ButtonMixin<T extends Constructor>(baseClass: T): T & Constructor<{ isButton: boolean }>; // 可选:定义Button实例的类型别名,方便在函数参数等场景使用 type ButtonInstance = { isButton: boolean };
验证使用场景
1. 直接实例化混入后的类
const imageButton = new (ButtonMixin(Image)); imageButton. // 智能提示会显示isImage、isButton
2. 继承混入后的类创建自定义类
class TextButton extends ButtonMixin(Text) { isTextButton: boolean; constructor() { super(); this.isTextButton = true; } } const textButton = new TextButton(); textButton. // 智能提示会显示isText、isButton、isTextButton
原理说明
Constructor<T>类型统一描述类的构造器,确保传入的baseClass是合法的类- 返回类型
T & Constructor<{ isButton: boolean }>表示:- 新构造器继承了基类
T的所有静态属性和构造能力(支持extends) - 新构造器的实例会包含基类实例的所有属性,加上
isButton属性
- 新构造器继承了基类
内容的提问来源于stack exchange,提问作者TarczaBoga
相关产品推荐
相关产品推荐

