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