2017-09-15 3 views
1

Pourquoi dois-je pirater la définition du type de material: Material | Material[]; à material: Material; pour corriger l'erreur détaillée ci-dessous? TypeScript suppose que le paramètre material est de type Material[] même si je l'ai explicitement défini sur Matériau. Est-ce que je manque quelque chose?Pourquoi mon paramètre est supposé être d'un type alors qu'il en est un autre?

Tapuscrit/ThreeJS Erreur:

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 Type Définition:

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

Veuillez lire [Pourquoi ne pas télécharger des images de code sur SO lorsque vous posez une question?] (Https://meta.stackoverflow.com/questions/285551/why-not-upload-images-of-code-on-so -when-ask-a-question) – Rabbid76

+0

Merci de nous avoir signalé @ Rabbid76. J'ai mis à jour la question et remplacé les images avec le code réel. –

Répondre

1

Pour autant que je peux dire de vos captures d'écran, la propriété material d'un objet Mesh pourrait soit être un Material objet ou un tableau de Material objets. TypeScript vous avertit utilement que vous traitez child.material comme un seul objet Material sans vérifier s'il en est réellement un.

Sauf si vous êtes absolument sûr que tous les cas de Mesh votre code ne sera jamais toucher a un seul objet Material et non un tableau comme sa propriété material, il est une mauvaise idée pour vous de modifier la définition de type dans la bibliothèque. Si le fichier de déclaration de bibliothèque est correct et que certains objets Mesh ont des tableaux d'objets Material, votre code se comportera incorrectement au moment de l'exécution dès que vous essaierez de définir la propriété shading d'un tableau.

Au lieu de cela, la bonne chose à faire serait de vérifier si child.material est un tableau, comme:

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); 
    } 

qui gère le cas du tableau en effectuant la même action sur chaque élément.

Ou, si vous êtes sûr que child.material est pas un tableau, vous pouvez faire quelque chose comme:

// Assert that it's not an array 
    const m = child.material as Material; 
    m.shading = THREE.SmoothShading; 
    m.side = THREE.DoubleSide; 

où vous dites tapuscrit vous savez que child.material est pas un tableau, en utilisant un type affirmation. Cela pourrait encore faire de mauvaises choses à l'exécution si votre affirmation s'avère être fausse, mais vous le savez sans doute mieux.

J'espère que l'une de ces solutions fonctionne pour vous. Bonne chance!

+0

Les deux méthodes fonctionnent parfaitement, merci! –