2017-09-15 106 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

這兩種方法都很完美,謝謝! –

相關問題