คุณสมบัติ 'ค่า' ไม่มีอยู่ในประเภท 'อ่านอย่างเดียว <{}>'


155

ฉันต้องสร้างแบบฟอร์มที่จะแสดงบางสิ่งตามค่าตอบแทนของ API ฉันกำลังทำงานกับรหัสต่อไปนี้:

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {value: ''};

    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleChange(event) {
    this.setState({value: event.target.value});
  }

  handleSubmit(event) {
    alert('A name was submitted: ' + this.state.value); //error here
    event.preventDefault();
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          Name:
          <input type="text" value={this.state.value} onChange={this.handleChange} /> // error here
        </label>
        <input type="submit" value="Submit" />
      </form>
    );
  }
}

ฉันได้รับข้อผิดพลาดต่อไปนี้:

error TS2339: Property 'value' does not exist on type 'Readonly<{}>'.

ฉันได้รับข้อผิดพลาดนี้ในสองบรรทัดที่ฉันแสดงความคิดเห็นเกี่ยวกับรหัส รหัสนี้ไม่ได้เป็นของฉันฉันได้รับจากเว็บไซต์อย่างเป็นทางการของปฏิกิริยา ( https://reactjs.org/docs/forms.html ) แต่มันไม่ทำงานที่นี่

ฉันใช้เครื่องมือ create-react-app


โกหกปัญหาของคุณที่อื่น - ดูการสาธิตนี้
เท็ด

ฉันรู้ว่ามันทำงานบนเว็บไซต์ "คอมไพเลอร์" ทั้งหมด แต่พวกเขาแนะนำให้ฉันใช้สิ่งนี้เพื่อทำโครงการgithub.com/Microsoft/TypeScript-React-Starterและผ่านผู้จัดพิมพ์ TypeScript มันไม่ทำงาน
Luis Henrique Zimmermann

คำตอบ:


264

Component ถูกกำหนดไว้เช่นดังนั้น:

interface Component<P = {}, S = {}> extends ComponentLifecycle<P, S> { }

หมายความว่าประเภทเริ่มต้นสำหรับรัฐ (และอุปกรณ์ประกอบฉาก) {}เป็น:
หากคุณต้องการให้องค์ประกอบของคุณvalueอยู่ในสถานะคุณต้องกำหนดเช่นนี้:

class App extends React.Component<{}, { value: string }> {
    ...
}

หรือ:

type MyProps = { ... };
type MyState = { value: string };
class App extends React.Component<MyProps, MyState> {
    ...
}

3
อืมมม, เพื่อน ๆ , มันใช้งานได้แล้ว, ตอบคำถามอีกอย่างซินแท็กซ์นี้เกี่ยวข้องกับ TypeScript ใช่มั้ย เพราะในการทำปฏิกิริยาเว็บไซต์อย่างเป็นทางการมันไม่ได้มีอะไรที่คล้ายกัน
Luis Henrique Zimmermann

3
ใช่มันเกี่ยวข้องกับตัวพิมพ์ดีดอย่างเคร่งครัด
Nitzan Tomer

1
นิยามที่ถูกต้องคือ: class Square ขยาย React.Component <{value: string}, {}> {... }
Rodrigo Perez Burgues

58

นอกจากคำตอบของ @ nitzan-tomer คุณยังมีตัวเลือกในการใช้งานinferfaces :

interface MyProps {
  ...
}

interface MyState {
  value: string
}

class App extends React.Component<MyProps, MyState> {
  ...
}

// Or with hooks, something like

const App = ({}: MyProps) => {
  const [value, setValue] = useState<string>(null);
  ...
};

ทั้งสองเป็นเรื่องปกติตราบใดที่คุณสอดคล้อง


1
โปรดสรุปความหมายที่สอดคล้องกันในบริบทของโพสต์ของคุณเพื่อให้เป็นไปได้ที่จะมีคุณค่าอย่างเต็มที่โดยไม่จำเป็นต้องอ่านบทความขนาดกลาง (ซึ่งเป็นลิงค์ที่มีประโยชน์มากขอบคุณ)
Karl Richter

9

ปัญหาคือคุณยังไม่ได้ประกาศสถานะอินเทอร์เฟซของคุณแทนที่ใด ๆ ด้วยประเภทตัวแปรที่เหมาะสมของคุณของ 'ค่า'

นี่คือการอ้างอิงที่ดี

interface AppProps {
   //code related to your props goes here
}

interface AppState {
   value: any
}

class App extends React.Component<AppProps, AppState> {
  // ...
}

0

event.targetเป็นประเภทEventTargetที่ไม่ได้มีค่าเสมอไป หากเป็นองค์ประกอบ DOM คุณต้องแปลงเป็นประเภทที่ถูกต้อง:

handleChange(event) {
    this.setState({value: (event.target as HTMLInputElement).value});
}

สิ่งนี้จะอนุมานชนิด "ถูกต้อง" สำหรับตัวแปรสถานะรวมถึงการมีความชัดเจนน่าจะดีกว่า


ฉันคิดว่าเขาได้รับข้อผิดพลาดเมื่อพยายามเริ่มต้นสตริงในตัวสร้างไม่ใช่ตัวจัดการเหตุการณ์
Ray_Poly
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.