2017-04-12 13 views
1

我想弄清楚canvas元素的正确类型。 无论我做什么 - 它都不起作用。我尝试了所有可能的html元素类型,但流程表示它们不兼容。那么,为什么不能将canvas元素分配给HTMLCanvasElement变量?Canvas元素的正确类型

任何想法?

node参数是一个div元素,它包含canvas元素。真的很简单。如果我去掉这些类型,那么一切正常。

export class Graph extends Component { 
     draw = (node: HTMLDivElement) => { 
     let canvas: HTMLCanvasElement = node.firstChild 
     if (canvas){ 
      canvas.width = parseInt(getComputedStyle(node).getPropertyValue('width')) 
      canvas.height = parseInt(getComputedStyle(node).getPropertyValue('height')) 
     } 
     let chart = new Chart(canvas, { 
      type: this.props.type, 
      data: this.props.data 
     }) 
     } 
     render =() => (
     <div ref={this.draw} className='graph'> 
      <canvas /> 
     </div> 
    ) 
    } 

我从流动棉短绒得到这些错误:

Node This type is incompatible with HTMLCanvasElement 
null This type is incompatible with HTMLCanvasElement 
undefined This type is incompatible with HTMLCanvasElement 

感谢

附:它是地狱 - 不反应。所以ref是一个函数,而不是一个字符串。只是为了避免人们纠正这一点。

回答

1

它看起来像HTMLDivElement不流内部定义: https://github.com/facebook/flow/blob/v0.43.1/lib/dom.js#L2811

HTMLDivElementHTMLCanvasElement是同胞类型(的HTMLElement两个孩子),所以自然而然地会说,这是不安全的尝试投HTMLDivElementHTMLCanvasElement因为你通常从来不想在任何类型的系统中执行此操作。

你可以击败Flow的类型系统,并通过将node.firstChild转换为any来解决此问题。这通常不被推荐,但在这种情况下似乎可以接受,因为HTMLDivElement不会给你任何东西,你一定知道它是什么。

let canvas: HTMLCanvasElement = (node.firstChild: any) 

feel free to also view the flowtype.org/try link

+0

非常感谢您的建议。但我避免使用“任何”。它有点挫败了一个类型系统的观点。我知道我可以像这样工作。那么我可以分配什么类型的变量canvas元素? –

+0

在这种情况下使用'any'的暴露程度将与其余类型相比,它应该没有太多,因为您只是将'node.firstChild'强制转换为'any',以便将其重新转换为'HTMLCanvasElement'来解决Flow中的类型转换限制。 –

+0

虽然可以定义更好的HTMLDivElement类型,但要定义能理解“node.firstChild”类型的泛型是非常困难的。您可能可以定义一个定义node.firstChild的非泛型子类型的HTMLDivElement,它是您的HTMLCanvasElement –