如何为包含多个不同类构造函数的接口编写正确类型?
为包含类构造函数的对象编写TypeScript类型定义
要正确类型化导出的bigObject,核心是在TypeScript中用构造签名表示类的构造函数(而非实例类型)。以下是两种可行的实现方式:
方式一:使用declare class(简洁直接)
这种方式通过declare class同时定义类的实例类型和构造函数类型,适合需要完整描述类结构的场景:
// 声明ThingTwo类的结构 declare class ThingTwo { constructor(par1: string, par2: boolean); // 在这里添加ThingTwo的其他实例方法/属性类型 } // 声明ThingOne类的结构,依赖ThingTwo实例 declare class ThingOne { constructor(par1: ThingTwo, par2: number); aMethod(par: string): void; // 在这里添加ThingOne的其他实例方法/属性类型 } // 定义bigObject的接口,属性为对应类的构造函数类型 interface BigObject { ThingOne: typeof ThingOne; ThingTwo: typeof ThingTwo; } // 声明导出的bigObject变量 declare const bigObject: BigObject; export default bigObject;
方式二:接口+构造函数类型(灵活解耦)
如果需要将实例类型和构造函数类型分开定义,可采用这种方式:
// 定义ThingTwo的实例类型 interface ThingTwoInstance { // 定义ThingTwo实例的属性和方法 } // 定义ThingTwo的构造函数类型:new + 参数 + 返回实例 type ThingTwoConstructor = new (par1: string, par2: boolean) => ThingTwoInstance; // 定义ThingOne的实例类型 interface ThingOneInstance { aMethod(par: string): void; // 定义ThingOne实例的其他属性和方法 } // 定义ThingOne的构造函数类型,依赖ThingTwoInstance type ThingOneConstructor = new (par1: ThingTwoInstance, par2: number) => ThingOneInstance; // 定义bigObject的接口 interface BigObject { ThingOne: ThingOneConstructor; ThingTwo: ThingTwoConstructor; } // 声明导出的bigObject变量 declare const bigObject: BigObject; export default bigObject;
验证类型正确性
使用上述类型定义后,TypeScript会自动检查代码的类型合法性:
// 合法用法 const myTwo = new bigObject.ThingTwo('foo', true); const myOne = new bigObject.ThingOne(myTwo, 7); myOne.aMethod('test'); // 非法用法会被TS报错 new bigObject.ThingTwo(123, 'bar'); // 参数类型不匹配 new bigObject.ThingOne('invalid', '7'); // 参数类型不匹配 myOne.aMethod(123); // 方法参数类型不匹配
内容的提问来源于stack exchange,提问作者Glen Whitney
相关产品推荐
相关产品推荐

