为什么我必须破解从material: Material | Material[];到material: Material;的类型定义来修复下面详述的错误?TypeScript似乎假设material参数是Material[]类型的,即使我显式地将它设置为Material。我是不是遗漏了什么?
类型记录/ThreeJS错误:
this.obj3D.traverse((child) => {
if (child instanceof THREE.Mesh) {
// Error in line below:
// Property 'shading' does not exist on type 'Material | Material
child.material.shading = THREE.SmoothShading;
child.material.side = THREE.DoubleSide;
child.scale.set(this.scale, this.scale, this.scale);
child.castShadow = this.castShadow;
child.receiveShadow = true;
child.material.needsUpdate = true;
}
});ThreeJS类型定义:
export class Mesh extends Object3D {
constructor(geometry?: Geometry, material?: Material | Material[]);
constructor(geometry?: BufferGeometry, material?: Material | Material[]);
geometry: Geometry | BufferGeometry;
material: Material | Material[]; // Had to delete *| Material[]* to fix
drawMode: TrianglesDrawModes;
setDrawMode(drawMode: TrianglesDrawModes): void;
updateMorphTargets(): void;
getMorphTargetIndexByName(name: string): number;
raycast(raycaster: Raycaster, intersects: any): void;
}发布于 2017-09-15 13:55:48
据我从屏幕截图中可以看出,Mesh对象的Mesh属性可以是Material对象或Material对象的数组。TypeScript很有帮助地警告您,您将child.material作为单个Material对象对待,而不检查它是否真的是Material对象。
除非您绝对确信您的代码将触及的每个Mesh实例都有一个Material对象,而不是一个数组作为其material属性,否则更改库中的类型定义对您来说是个坏主意。如果库声明文件是正确的,并且一些Mesh对象具有Material对象数组,那么当您试图设置数组的shading属性时,您的代码在运行时就会表现得不正确。
相反,正确的做法是检查child.material是否是一个数组,例如:
const doStuffToMaterial = function(m: Material):void {
m.shading = THREE.SmoothShading;
m.side = THREE.DoubleSide;
}
// check for an array
if (Array.isArray(child.material)) {
child.material.forEach(doStuffToMaterial);
} else {
doStuffToMaterial(child.material);
}它通过对每个元素执行相同的操作来处理数组案例。
或者,如果您确信child.material不是数组,则可以执行以下操作:
// Assert that it's not an array
const m = child.material as Material;
m.shading = THREE.SmoothShading;
m.side = THREE.DoubleSide;通过使用类型断言告诉TypeScript,您知道child.material不是数组。如果您的断言被证明是错误的,那么这仍然可能在运行时做不好的事情,但是您大概知道得更清楚。
我希望其中一个解决方案对你有用。祝好运!
https://stackoverflow.com/questions/46237082
复制相似问题