2017-09-15 107 views
1

为什么我必须将类型定义从material: Material | Material[];修改为material: Material;才能解决下面详述的错误? TypeScript看似假设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; 
} 
+4

请阅读[为什么不上传图片的代码时提问?](https://meta.stackoverflow.com/questions/285551/why-not-upload-images-of-code-on-so - 当问一个问题) – Rabbid76

+0

感谢您指出@ Rabbid76。我更新了问题并用实际代码替换了图片。 –

回答

1

据我可以从你的截图出来,一个Mesh对象的material财产既可以是Material对象Material对象的数组。 TypeScript有助于警告您,您将child.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; 

您告诉打字稿你知道child.material不是数组,通过使用类型断言。如果你的断言结果是错误的,这仍然可以在运行时做坏事,但大概你知道的更好。

我希望其中一种解决方案适合您。祝你好运!

+0

这两种方法都很完美,谢谢! –

相关问题