Thuộc tính 'giá trị' không tồn tại trên loại EventTarget trong TypeScript


118

Vì vậy, đoạn mã sau nằm trong Angular 4 và tôi không thể tìm ra lý do tại sao nó không hoạt động theo cách như mong đợi.

Đây là một đoạn mã của trình xử lý của tôi:

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

Phần tử HTML:

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

Mã cho tôi lỗi:

Thuộc tính "value" không tồn tại trên loại "EventTarget".

Nhưng như có thể thấy trong console.loggiá trị đó tồn tại trên event.target.


2
chúng ta có thể sử dụng (e.target như HTMLInputElement) .Value
user1162084

Câu trả lời:


146

event.targetđây là một HTMLElementphần tử gốc của tất cả các phần tử HTML, nhưng không được đảm bảo có thuộc tính value. TypeScript phát hiện điều này và xử lý lỗi. Truyền event.targettới phần tử HTML thích hợp để đảm bảo phần tử HTMLInputElementnày có thuộc valuetính:

(<HTMLInputElement>event.target).value

Theo tài liệu :

Nhập $event

Ví dụ trên sử $eventdụng một anykiểu. Điều đó đơn giản hóa mã với chi phí. Không có thông tin kiểu nào có thể tiết lộ các thuộc tính của đối tượng sự kiện và ngăn chặn những sai lầm ngớ ngẩn.

[...]

Các $eventbây giờ là một cụ thể KeyboardEvent. Không phải tất cả các phần tử đều có một thuộc valuetính để nó targetchuyển thành một phần tử đầu vào.

(Tôi nhấn mạnh)


26
Cú pháp gọn gàng hơn một chútvar element = ev.target as HTMLElement
Adrian Moisa

Đối với tôi, HTMLInputElement hoạt động thay vì HTMLElement vì HTMLElement không có giá trị trong giao diện.
Harsha Vardhini ngày

Cách tiếp cận tốt nhất, theo ý kiến ​​của tôi, là có onFieldUpdate(event: { target: HTMLInputElement }) {trong chức năng được gọi. Xem câu trả lời của tôi dưới đây.
belvederef

Đối với Angular 9, hãy sử dụng cú pháp "as". event.target as HtmlInputlement
Prescol

86

Việc chuyển HTMLInputElement dưới dạng chung cho loại sự kiện cũng sẽ hoạt động:

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

14
Điều này tốt hơn các xác nhận kiểu.
JamesYin

2
Điều này sẽ không hoạt động nếu hàm được gọi từ một onChangetham chiếu trình xử lý proeperty trong mã React. Trình xử lý phản ứng không mong đợi loại được đặt cho React.ChangeEvent và sẽ hiển thị lỗi nhập. Tôi đã phải trở lại (một biến thể của) câu trả lời được lựa chọn thay vào đó, với một dàn diễn viên: (event.target as HTMLInputElement).value.
Spiralis

Điều này dường như hoạt động tốt đối với tôi trong một thành phần React. Có lẽ đó là phiên bản của React? Chúng tôi hiện đang ở trên 16.8. *.
hellatan

49

Đây là một bản sửa lỗi khác phù hợp với tôi:

(event.target as HTMLInputElement).value

Điều đó sẽ loại bỏ lỗi bằng cách cho TS biết rằng đó event.targetlà một HTMLInputElement, mà vốn có một value. Trước khi chỉ định, TS có thể chỉ biết rằng eventmột mình là một HTMLInputElement, do đó theo TS, keyed-in targetlà một số giá trị được ánh xạ ngẫu nhiên có thể là bất kỳ thứ gì.


4
Điều này thực sự hữu ích trong React khi nó cố gắng diễn giải <HTMLInputElement> là JSX.
Christopher Bradshaw

Này người đàn ông, cảm ơn vì đã chia sẻ! Giải pháp này phù hợp với tôi.
Carlos Querioz

16

Tôi đang tìm giải pháp cho một lỗi TypeScript tương tự với React:

Thuộc tính 'tập dữ liệu' không tồn tại trên loại EventTarget trong TypeScript

Tôi muốn truy cập event.target.datasetvào phần tử nút được nhấp trong React:

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

Đây là cách tôi có thể lấy datasetgiá trị để "tồn tại" thông qua 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
Câu hỏi được gắn thẻ là Angular nên câu trả lời của React có vẻ lạc đề.
John Snow

2
Bất kể… nó có nhiều phiếu bầu, do đó câu trả lời này rất hữu ích cho những người khác.
Beau Smith

1
Hoạt động như một sự quyến rũ. onChange={(event: ChangeEvent<HTMLInputElement>): void => { setTextFilter(event.target.value); }}
Vadorequest

2

Bạn nên sử dụng event.target.valueprop với trình xử lý onChange nếu không, bạn có thể thấy:

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`.

Hoặc Nếu bạn muốn sử dụng trình xử lý khác ngoài onChange, hãy sử dụng event.currentTarget.value


điều này phù hợp với tôi nhưng tôi không chắc sử dụng event.currentTarget.valuelà cách tiếp cận tốt nhất.
dczii

2

Cách tôi làm như sau (tốt hơn kiểu khẳng định imho):

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

Điều này giả định rằng bạn chỉ quan tâm đến targettài sản, đây là trường hợp phổ biến nhất. Nếu bạn cần truy cập các thuộc tính khác của event, một giải pháp toàn diện hơn liên quan đến việc sử dụng &toán tử giao nhau kiểu:

event: Event & { target: HTMLInputElement }

Đây là phiên bản Vue.js nhưng khái niệm này áp dụng cho tất cả các khuôn khổ. Rõ ràng là bạn có thể đi cụ thể hơn và thay vì sử dụng chung chung, HTMLInputElementbạn có thể sử dụng ví dụ: HTMLTextAreaElementcho textareas.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.