我将 TypeScript 版本 2 用于 Angular 2 组件代码。
对于下面的代码,我收到错误“'EventTarget' 类型上不存在属性'值'”,可能是什么解决方案。谢谢!
e.target.value.match(/\S+/g) || []).length
import { Component, EventEmitter, Output } from '@angular/core';
@Component({
selector: 'text-editor',
template: `
<textarea (keyup)="emitWordCount($event)"></textarea>
`
})
export class TextEditorComponent {
@Output() countUpdate = new EventEmitter<number>();
emitWordCount(e: Event) {
this.countUpdate.emit(
(e.target.value.match(/\S+/g) || []).length);
}
}
您需要明确告诉 TypeScript 您的目标 HTMLElement 的类型。
这样做的方法是使用泛型类型将其转换为正确的类型:
this.countUpdate.emit((<HTMLTextAreaElement>e.target).value./*...*/)
或(如你所愿)
this.countUpdate.emit((e.target as HTMLTextAreaElement).value./*...*/)
或(再次,偏好问题)
const target = e.target as HTMLTextAreaElement;
this.countUpdate.emit(target.value./*...*/)
这将使 TypeScript 知道该元素是 textarea
并且它会知道 value 属性。
任何类型的 HTML 元素都可以这样做,只要您向 TypeScript 提供有关其类型的更多信息,它就会以适当的提示和当然更少的错误来回报您。
为了使将来更容易,您可能希望直接使用其目标类型定义事件:
// create a new type HTMLElementEvent that has a target of type you pass
// type T must be a HTMLElement (e.g. HTMLTextAreaElement extends HTMLElement)
type HTMLElementEvent<T extends HTMLElement> = Event & {
target: T;
// probably you might want to add the currentTarget as well
// currentTarget: T;
}
// use it instead of Event
let e: HTMLElementEvent<HTMLTextAreaElement>;
console.log(e.target.value);
// or in the context of the given example
emitWordCount(e: HTMLElementEvent<HTMLTextAreaElement>) {
this.countUpdate.emit(e.target.value);
}
这是我使用的简单方法:
const element = event.currentTarget as HTMLInputElement
const value = element.value
TypeScript 编译器显示的错误消失了,代码可以正常工作。
由于我遇到了两个问题,以稍微不同的方式搜索我的问题,因此我正在复制我的答案,以防你最终来到这里。
在被调用的函数中,您可以使用以下方式定义您的类型:
emitWordCount(event: { target: HTMLInputElement }) {
this.countUpdate.emit(event.target.value);
}
这假设您只对 target
属性感兴趣,这是最常见的情况。如果您需要访问 event
的其他属性,更全面的解决方案涉及使用 &
类型的交集运算符:
event: Event & { target: HTMLInputElement }
您还可以更具体,而不是使用 HTMLInputElement
,您可以使用例如 HTMLTextAreaElement
来表示文本区域。
角度 10+
打开 tsconfig.json
并禁用 strictDomEventTypes
。
"angularCompilerOptions": {
....
........
"strictDomEventTypes": false
}
(keyup)="doFilter(($event.target as HTMLTextAreaElement).value)"
就我而言,我有:
const handleOnChange = (e: ChangeEvent) => {
doSomething(e.target.value);
}
问题是我没有向 ChangeEvent 提供类型参数,以便它知道 e.target
是 HTMLInputElement
。即使我手动告诉它 target
是一个输入元素(例如 const target: HTMLInputElement = e.target
),ChangeEvent
仍然不知道这是有道理的。
解决方案是:
// add type argument
const handleOnChange = (e: ChangeEvent<HTMLInputElement>) => {
doSomething(e.target.value);
}
考虑 $any()
<textarea (keyup)="emitWordCount($any($event))"></textarea>
$any($event.target).value
,这会将 event.target
属性标记为 any
,您可以访问该值。
$any($event.target).checked
对于那些在 Angular 13 中遇到此错误的人,因为从以前的版本升级
对我来说,问题是我在我的 HTML 中使用了以下内容(之前是允许的)
(keyup)="applyFilter($event.target.value)"
对此的修复是:
HTML:
(keyup)="applyFilter($event)"
组件 - 在我调用的函数中:
applyFilter(event: Event) {
const filterValue = (event.target as HTMLInputElement).value;
// ... etc....
}
现在我可以像以前一样再次使用 filterValue 来过滤页面中的值
Event
工作。
这是我使用的另一种简单方法;
inputChange(event: KeyboardEvent) {
const target = event.target as HTMLTextAreaElement;
var activeInput = target.id;
}
fromEvent<KeyboardEvent>(document.querySelector('#searcha') as HTMLInputElement , 'keyup')
.pipe(
debounceTime(500),
distinctUntilChanged(),
map(e => {
return e.target['value']; // <-- target does not exist on {}
})
).subscribe(k => console.log(k));
也许像上面这样的东西会有所帮助。根据真实代码进行更改。问题是........ target['value']
角 11+
打开 tsconfig.json
并禁用 strictTemplates
。
"angularCompilerOptions": {
....
........
"strictTemplates": false
}
不要使用涉及投射事件、事件目标或完全禁用类型检查的其他答案的解决方法。这是不安全的。
相反,您应该从 HTML 元素中“提取”值并将其作为参数传递。
过于简单的例子:
<input #searchBox type="text" (input)="doSearch(searchBox.value)">
doSearch(text: string): void {
}
因此,如果您将其扩展到原始示例,您应该得到:
import { Component, EventEmitter, Output } from '@angular/core';
@Component({
selector: 'text-editor',
template: `
<textarea #text (keyup)="emitWordCount(text.value)"></textarea>
`
})
export class TextEditorComponent {
@Output() countUpdate = new EventEmitter<number>();
emitWordCount(text: string) {
this.countUpdate.emit(
(text.match(/\S+/g) || []).length);
}
}
最好的方法是使用模板 => 将 id 添加到您的输入中,然后使用它的值
searchNotary(value: string) {
// your logic
}
这样,当激活严格验证时,您将永远不会出现 Typescript 错误 => 请参阅 angular Docs
用户 TypeScript 内置实用程序类型 Partial<Type>
在您的模板中
(keyup)="emitWordCount($event.target)"
在您的组件中
emitWordCount(target: Partial<HTMLTextAreaElement>) {
this.countUpdate.emit(target.value./*...*/);
}
"strictDomEventTypes": true
。还使用 Partial<HTMLInputElement>
进行输入
我相信它必须有效,但我无法识别任何方式。其他方法可以是,
<textarea (keyup)="emitWordCount(myModel)" [(ngModel)]="myModel"></textarea>
export class TextEditorComponent {
@Output() countUpdate = new EventEmitter<number>();
emitWordCount(model) {
this.countUpdate.emit(
(model.match(/\S+/g) || []).length);
}
}
这是指定 event.target
的另一种方法:
从'@angular/core'导入{组件,EventEmitter,输出}; @Component({ selector: 'text-editor', template: `` }) export class TextEditorComponent { @Output() countUpdate = new EventEmitter
请改用 currentValue
,因为 currentValue 的类型是 EventTarget & HTMLInputElement
。
<img [src]="url"> <br/> <input type='file' (change)="showImg($event)">
组件:... this.url = event.target.result;
有时工作有时不工作,当它不是错误时error TS2339: Property 'result' does not exist on type 'EventTarget'
正如你所建议的告诉 TS 更多关于它,在HTMLTextAreaElement
我尝试HTMLInputElement
然后target.value
没有更多错误但图像未显示。Event
类型,我感到很惊讶。您确实应该能够使用Event<HTMLInputElement>
作为类型。target
、currentTarget
和srcElement
;需要输入 3 个泛型类型;即使他们使用默认类型,例如上面提到的Event<T = any, C = any, S = any>
,它也可能比简单的as
语句更不舒服。我还可以想象一场潜在的圣战,首先应该是通用的:target
或currentTarget
。此外,许多库滥用 HTML 事件,并可能将他们想要的任何内容放在提到的属性中。可能这些是他们没有将其作为内置泛型的原因(ionChangeEvent.target as HTMLIonInputElement).value as string