能否为TypeScript的type类型创建支持new语法的构造函数?
可以实现,但需要调整写法
TypeScript里的type只是编译时的类型定义,编译后会被完全移除,没有对应的运行时实体,所以没法直接给它加构造函数让你用new语法。不过你可以通过两种方式实现类似效果:
方案1:用类替代(推荐)
把原来的类型定义和构造逻辑合并成一个类,类在TS中既是类型也是运行时的构造函数,完美匹配你的需求:
export enum Category { a='a', e='e', i='i', o='o', u='u' }; // 类本身就可以作为类型使用,也可以保留原type别名(可选) export type CategorisedItems = InstanceType<typeof CategorisedItems>; export class CategorisedItems { constructor() { // 把原来工厂函数的初始化逻辑移到构造函数里 Object.assign(this, ...Object.values(Category).map(category => ({[category]: []}))); } }
这样使用时就可以直接用new语法,和你想要的写法完全一致:
import { CategorisedItems } from './categories'; export class PendingData { public readonly categorisedItems: CategorisedItems = new CategorisedItems(); }
这种方式还有额外好处:如果以后需要给CategorisedItems添加方法(比如添加元素、统计数量),直接在类里加就行,比工厂函数返回的普通对象更易扩展。
方案2:手动构造函数(不推荐,仅作参考)
如果不想用类,也可以手动创建一个构造函数函数,再通过类型关联让TS识别它:
export enum Category { a='a', e='e', i='i', o='o', u='u' }; export type CategorisedItems = { [category in Category]: string[] }; // 定义构造函数,用this参数指定实例类型 export function CategorisedItems(this: CategorisedItems) { Object.assign(this, ...Object.values(Category).map(category => ({[category]: []}))); } // 告诉TS这个函数可以作为构造函数使用 export namespace CategorisedItems { export type Instance = CategorisedItems; } // 使用时需要做类型断言让TS认可它是构造函数 const items = new (CategorisedItems as new () => CategorisedItems)();
这种方式比较繁琐,而且不如类直观,一般不推荐。
注意点
用类实现的话,实例会是CategorisedItems类的实例(instanceof CategorisedItems为true),而原来工厂函数返回的是普通对象。如果你的代码里只依赖结构而不依赖实例类型,这个差异可以忽略;如果需要保持和原工厂函数返回的对象一致(都是普通对象),那还是用工厂函数更合适,但就没法用new语法了。
内容的提问来源于stack exchange,提问作者Hand-E-Food
相关产品推荐
相关产品推荐

