在Three.js调试中,能否用TypeScript模板字符串类型自动推断globalThis键类型?
解决TypeScript自动识别globalThis上特定后缀键的类型问题
问题场景
在Three.js调试过程中,为了便捷操作会将各类对象挂载到globalThis上,但随着挂载对象数量增加,手动逐个声明每个属性的类型变得繁琐。希望TypeScript能自动推断所有以Material结尾的键(匹配模板字符串类型${string}Material),将它们的类型统一设为THREE.MeshPhysicalMaterial,省去重复手动声明的工作。
比如原本需要手动编写大量重复声明:
declare global { var camera: THREE.PerspectiveCamera var scene: THREE.Scene var renderer: THREE.WebGLRenderer var setCameraToLeft: () => void var setCameraToRight: () => void var bigBoxMaterial: THREE.MeshPhysicalMaterial var middleBoxMaterial: THREE.MeshPhysicalMaterial var smallBoxMaterial: THREE.MeshPhysicalMaterial // 更多xxxMaterial属性... }
实现方案
TypeScript支持模板字符串索引签名,但直接使用索引签名会覆盖显式声明的属性类型,因此需要结合接口扩展来实现需求:
写法一:拆分接口扩展
declare global { // 声明固定属性 interface Window { camera: THREE.PerspectiveCamera scene: THREE.Scene renderer: THREE.WebGLRenderer setCameraToLeft: () => void setCameraToRight: () => void } // 定义匹配Material后缀的索引签名类型 type MaterialProperties = { [K in `${string}Material`]: THREE.MeshPhysicalMaterial } // 让Window接口扩展该类型,自动应用后缀匹配规则 interface Window extends MaterialProperties {} }
写法二:合并声明
declare global { // 手动声明固定属性 var camera: THREE.PerspectiveCamera var scene: THREE.Scene var renderer: THREE.WebGLRenderer var setCameraToLeft: () => void var setCameraToRight: () => void // 扩展Window接口,添加模板字符串索引签名 interface Window extends { [K in `${string}Material`]: THREE.MeshPhysicalMaterial } {} }
效果说明
- 所有以
Material结尾的属性(如floorMaterial、wallMaterial)会被TypeScript自动识别为THREE.MeshPhysicalMaterial类型,无需手动声明。 - 手动声明的固定属性(如
camera、scene)的类型不受影响,依然保持原有定义。
内容的提问来源于stack exchange,提问作者TomWang
相关产品推荐
相关产品推荐

