TypeScript:对象内部类的显式类型赋值问题求助
为什么无法用
obj.hello作为显式类型注解? 这个问题其实是TypeScript类型系统和值系统分离的规则导致的——你不能直接用一个值的访问路径(比如obj.hello)来引用它的类型,哪怕这个值是个类。obj.hello在这里只能作为值被调用(比如new obj.hello()),但不能直接当作类型标识符来用,这就是为什么inst2会退化为any的原因。
我给你提供几种可行的解决办法:
方法1:预先定义类,再挂载到对象上
最直观的方式是先把类单独定义出来,这样就有了明确的类型标识符,之后再把它放到对象里:
// 先定义类,同时得到类的类型 class HelloClass { constructor() { console.log('hi'); } } let obj = { hello: HelloClass } // 直接用预先定义的类作为类型注解 var inst2: HelloClass; function assign() { inst2 = new obj.hello(); }
这种方式最清晰,适合类逻辑比较复杂、需要复用类型的场景。
方法2:使用typeof和InstanceType工具类型
如果不想单独定义类,可以用TypeScript的类型查询工具来提取对象中类的类型:
let obj = { hello: class { constructor() { console.log('hi'); } } } // 用typeof获取类构造函数的类型,再用InstanceType提取实例类型 var inst2: InstanceType<typeof obj.hello>; function assign() { inst2 = new obj.hello(); }
这里typeof obj.hello会获取到类的构造函数类型,InstanceType工具类型则会从构造函数类型中提取出对应的实例类型,这样inst2就会拥有正确的类型信息,不再是any。
方法3:通过接口定义对象类型
如果需要复用这个对象的结构,可以先定义一个接口来明确hello的类型:
// 定义接口,明确hello是一个无参构造函数,返回实例类型 interface ObjWithHello { hello: new () => { // 这里可以添加类实例的属性、方法定义 }; } let obj: ObjWithHello = { hello: class { constructor() { console.log('hi'); } } } // 从接口中提取hello的构造函数类型,再取实例类型 var inst2: InstanceType<ObjWithHello['hello']>; function assign() { inst2 = new obj.hello(); }
这种方式适合需要约束多个同结构对象的场景,类型定义更严谨。
总的来说,核心就是要区分TypeScript中的值和类型两个系统:值可以通过路径访问,但类型需要明确的标识符或者通过类型工具来提取,这样才能让类型系统正确识别嵌套在对象里的类的实例类型。
内容的提问来源于stack exchange,提问作者Allan Jardine
相关产品推荐
相关产品推荐

