ไม่มีคุณสมบัติ 'value' ในประเภท EventTarget ใน TypeScript


121

ดังนั้นรหัสต่อไปนี้จึงอยู่ใน Angular 4 และฉันคิดไม่ออกว่าทำไมมันถึงไม่ได้ผลอย่างที่คาด

นี่คือตัวอย่างของเครื่องจัดการของฉัน:

onUpdatingServerName(event: Event) {
  console.log(event);
  this.newserverName = event.target.value; //this wont work
}

องค์ประกอบ HTML:

<input type="text" class="form-control" (input)="onUpdatingServerName($event)">

รหัสทำให้ฉันมีข้อผิดพลาด:

ไม่มีคุณสมบัติ 'value' ในประเภท 'EventTarget'

แต่อย่างที่เห็นได้ในconsole.logค่านั้นมีอยู่ในไฟล์event.target.


2
เราสามารถใช้ (e.target เป็น HTMLInputElement)
.value

คำตอบ:


149

event.targetที่นี่เป็นที่HTMLElementซึ่งเป็นแม่ขององค์ประกอบ HTML ทั้งหมด valueแต่ไม่รับประกันว่าจะมีคุณสมบัติ TypeScript ตรวจพบสิ่งนี้และแสดงข้อผิดพลาด แคสevent.targetต์ไปยังองค์ประกอบ HTML ที่เหมาะสมเพื่อให้แน่ใจว่าเป็นHTMLInputElementสิ่งที่มีvalueคุณสมบัติ:

(<HTMLInputElement>event.target).value

ตามเอกสารประกอบ :

พิมพ์ $event

ตัวอย่างด้านบนแสดง$eventเป็นanyประเภท ซึ่งทำให้โค้ดง่ายขึ้นโดยมีค่าใช้จ่าย ไม่มีข้อมูลประเภทใดที่สามารถเปิดเผยคุณสมบัติของออบเจ็กต์เหตุการณ์และป้องกันความผิดพลาดที่ไร้สาระ

[... ]

อยู่ในขณะนี้โดยเฉพาะ$event องค์ประกอบบางอย่างไม่ได้มีคุณสมบัติดังนั้นจึงส่งไปยังองค์ประกอบอินพุตKeyboardEventvaluetarget

(เน้นของฉัน)


27
ไวยากรณ์ที่สะอาดกว่าเล็กน้อยvar element = ev.target as HTMLElement
Adrian Moisa

สำหรับฉัน HTMLInputElement ทำงานแทน HTMLElement เนื่องจาก HTMLElement ไม่มีค่าในอินเทอร์เฟซ
Harsha Vardhini

1
แนวทางที่ดีที่สุดในความคิดของฉันคือมีonFieldUpdate(event: { target: HTMLInputElement }) {ในฟังก์ชันที่เรียกว่า ดูคำตอบของฉันด้านล่าง
belvederef

สำหรับ Angular 9 ให้ใช้ไวยากรณ์ "เป็น" event.target as HtmlInputlement
Prescol

88

การส่ง HTMLInputElement เป็นแบบทั่วไปไปยังประเภทเหตุการณ์ควรใช้งานได้เช่นกัน:

onUpdatingServerName(event: React.ChangeEvent<HTMLInputElement>) {
  console.log(event);
  this.newserverName = event.target.value;
}

14
ดีกว่าการยืนยันประเภท
JamesYin

2
สิ่งนี้จะไม่ทำงานหากฟังก์ชันถูกเรียกใช้จากเช่นการonChangeอ้างอิงตัวจัดการ proeperty ใน React code แม้ว่า ตัวจัดการการตอบสนองไม่คาดว่าจะกำหนดประเภทสำหรับ React.ChangeEvent และจะแสดงข้อผิดพลาดในการพิมพ์ ผมต้องกลับไปใช้ (แตกต่างจากก) (event.target as HTMLInputElement).valueคำตอบที่เลือกแทนด้วยหล่อ:
Spiralis

สิ่งนี้ดูเหมือนจะใช้ได้ผลสำหรับฉันในองค์ประกอบ React อาจจะเป็นรุ่นของ React? ขณะนี้เราอยู่ที่ 16.8 *.
hellatan

49

นี่คืออีกวิธีหนึ่งที่ใช้ได้ผลสำหรับฉัน:

(event.target as HTMLInputElement).value

นั่นควรกำจัดข้อผิดพลาดโดยแจ้งให้ TS รู้ว่าevent.targetเป็น an HTMLInputElementซึ่งโดยเนื้อแท้แล้วมีไฟล์value. ก่อนที่จะระบุ, TS แนวโน้มที่รู้เพียงeventคนเดียวเป็นHTMLInputElementจึงตาม TS คีย์ในtargetมูลค่าถูกบางแมปแบบสุ่มว่าจะเป็นอะไร


4
สิ่งนี้มีประโยชน์มากใน React ที่พยายามตีความ <HTMLInputElement> เป็น JSX
Christopher Bradshaw

สวัสดีขอบคุณสำหรับการแบ่งปัน! วิธีนี้เหมาะสำหรับฉัน
Carlos Querioz

16

ฉันกำลังมองหาวิธีแก้ไขข้อผิดพลาด TypeScript ที่คล้ายกันกับ React:

ไม่มีคุณสมบัติ 'ชุดข้อมูล' ในประเภท EventTarget ใน TypeScript

ฉันต้องการเข้าถึงevent.target.datasetองค์ประกอบปุ่มที่คลิกใน React:

<button
  onClick={onClickHandler}
  data-index="4"
  data-name="Foo Bar"
>
  Delete Candidate
</button>

นี่คือวิธีที่ฉันสามารถรับdatasetค่าเป็น "มีอยู่" ผ่าน TypeScript:

const onClickHandler = (event: React.MouseEvent<HTMLButtonElement>) => {
  const { name, index } = (event.target as HTMLButtonElement).dataset
  console.log({ name, index })
  // do stuff with name and index…
}

1
คำถามถูกแท็กเป็นเชิงมุมดังนั้นคำตอบที่ตอบสนองจึงดูเหมือนไม่อยู่ในหัวข้อ
John Snow

2
ไม่ว่า…จะมีการโหวตหลายครั้งคำตอบนี้จึงเป็นประโยชน์ต่อผู้อื่น
Beau Smith

1
ใช้งานได้เหมือนมีเสน่ห์ onChange={(event: ChangeEvent<HTMLInputElement>): void => { setTextFilter(event.target.value); }}
Vadorequest

4

วิธีที่ฉันทำมีดังต่อไปนี้ (ดีกว่าการยืนยันประเภท imho):

onFieldUpdate(event: { target: HTMLInputElement }) {
  this.$emit('onFieldUpdate', event.target.value);
}

สิ่งนี้จะถือว่าคุณสนใจในtargetทรัพย์สินเท่านั้นซึ่งเป็นกรณีที่พบบ่อยที่สุด หากคุณต้องการเข้าถึงคุณสมบัติอื่น ๆ ของeventโซลูชันที่ครอบคลุมมากขึ้นเกี่ยวข้องกับการใช้ตัว&ดำเนินการแยกประเภท:

event: Event & { target: HTMLInputElement }

นี่เป็นเวอร์ชัน Vue.js แต่แนวคิดนี้ใช้กับกรอบงานทั้งหมด เห็นได้ชัดว่าคุณสามารถเจาะจงได้มากขึ้นและแทนที่จะใช้แบบทั่วไปHTMLInputElementคุณสามารถใช้เช่นHTMLTextAreaElementสำหรับ textareas


2

คุณควรใช้event.target.valueprop ร่วมกับ onChange handler หากไม่เห็น:

index.js:1437 Warning: Failed prop type: You provided a `value` prop to a form field without an `onChange` handler. This will render a read-only field. If the field should be mutable use `defaultValue`. Otherwise, set either `onChange` or `readOnly`.

หรือหากคุณต้องการใช้ตัวจัดการอื่นที่ไม่ใช่ onChange ให้ใช้ event.currentTarget.value


วิธีนี้ใช้ได้กับฉัน แต่ฉันไม่แน่ใจว่าการใช้event.currentTarget.valueเป็นแนวทางที่ดีที่สุด
dczii

-2

เพิ่มประเภทใดก็ได้ในเหตุการณ์

event: any

ตัวอย่าง

[element].addEvenListener('mousemove', (event: any) =>{
//CODE//
} )

สิ่งที่เกิดขึ้นคือ typescript เพิ่มเหตุการณ์เป็นประเภทเหตุการณ์และด้วยเหตุผลบางประการมันไม่รู้จักคุณสมบัติบางอย่าง การเพิ่มประเภทใด ๆ ไม่มีปัญหานี้อีกต่อไปสิ่งนี้ใช้ได้กับทุกประเภทdocument.[Property]


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