ค้นหาเว็บไซต์

TypeScript - วิธีการกำหนดชนิดของคอมโพเนนต์ React?


ฉันกำลังพยายามที่จะระบุประเภทของ props ของคอมโพเนนต์ React แบบสถิติ หลังจากรวมคำนิยามสำหรับ React แล้ว ฉันได้กำหนดเวอร์ชันที่มีประเภทของ React.createClass ชื่อว่า component

interface Component<P> {
    (props: P, ...children: any[]): React.ReactComponent<P, any>
}

function component<P, S>(spec: React.ReactComponentSpec<P, S>): Component<P> {
    return React.createClass(spec);
}

เมื่อฉันกำหนดคอมโพเนนต์ Label ด้วยคำอธิบายประกอบที่ระบุว่ามันรับพร็อพ text เป็นสตริง,

var Label: Component<{text: string}> = component({
    render: function() {
        return React.DOM.div(null, this.props.text);
    }
});

var App = React.createClass({
    render: function() {
        return React.DOM.div(null, Label({text: "Hello"}));
    }
});

คอมไพเลอร์ตรวจสอบว่า Label ถูกเรียกด้วยคุณสมบัติ text และว่ามันเป็นสตริง

ขั้นตอนต่อไปคือให้คอมไพลเลอร์ตรวจสอบว่า this.props.text ถูกใช้ ภายใน เมธอดของ Label ทำอย่างไร?

คำตอบ #1

ฉันใช้สะพาน react-typescript ซึ่งกำหนดคลาสฐานที่สามารถใช้จาก TypeScript ได้:

class HelloMessage extends ReactTypescript.ReactComponentBase<{ name: string; }, {}> {
  render() {
    return React.DOM.div(null, 'Hello ' + this.props.name);
  }
}

เนื่องจากคลาสฐานเป็นแบบเจนเนอริก, this.props จึงถูกพิมพ์ประเภทอย่างถูกต้องเป็น { name: string; } ในตัวอย่างข้างต้น

คำตอบ #2

โดยพื้นฐานแล้ว คุณต้องการสร้างอินเทอร์เฟซสำหรับ Props และ State ของคุณและส่งต่อพวกมันเป็นชนิดของคลาสใหม่ที่สืบทอดจาก React.Component การใช้การกำหนดชนิดของ React หมายความว่าคุณไม่จำเป็นต้องเพิ่มชนิดสำหรับสิ่งใดนอกจากคลาสใหม่ที่คุณกำลังสร้าง คุณสามารถเห็นตัวอย่างนี้ในรูปแบบด้านล่าง

(ฉันเขียนโพสต์บล็อกเกี่ยวกับเรื่องนี้ที่นี่)

/// <reference path='../typings/react/react.d.ts' />
import React = require('react');

interface P {
  name?: string;
}

interface S {
  complete?: boolean;
}

class Goal extends React.Component<P, S> {
  state: S = {
    complete: false
  }

  private _toggleCompletion = () => {
    this.setState({complete: !this.state.complete});
  }

  render() {
    var status = 'Status: ' + (this.state.complete ? 'complete' : 'incomplete');
    return React.DOM.div({
      children: [
        React.DOM.div({}, this.props.name + ' - ' + status),
        React.DOM.button({
          onClick: this._toggleCompletion
        }, 'Toggle completion')
      ]
    });
  }
}

React.render(React.createElement(Goal, {name: 'Learn React and TypeScript'}), document.getElementById('react'));

บทความที่เกี่ยวข้อง