开启strictTemplates后如何解决非EventEmitter的Custom Event $event类型报错
问题根因
Angular 严格模板类型检查机制下,所有未在组件/指令中显式声明的DOM绑定事件,默认会将$event推导为最基础的Event类型,不会自动识别你通过dispatchEvent派发的CustomEvent子类,因此开启strictTemplates后会提示不存在detail属性。
解决方案
库侧最优方案:配套类型声明指令
你可以通过和组件同选择器的Angular指令为所有自定义事件做显式类型映射,不需要改动现有dispatchCustomEvent派发逻辑,也不需要用EventEmitter做事件派发,仅用指令做类型桥接即可:
- 首先定义所有自定义事件的参数类型映射
// 示例事件参数类型,可根据实际场景补充全量事件 type SlickGridEventMap = { onSelectedRowsChanged: { eventData: Event, args: OnSelectedRowsChangedEventArgs }; onCellClick: { eventData: Event, args: OnCellClickEventArgs }; onSort: { eventData: Event, args: OnSortEventArgs }; // 其余SlickGrid事件依次声明 }
- 编写配套指令,自动绑定到所有
angular-slickgrid组件实例
import { Directive, HostListener, Output, EventEmitter } from '@angular/core'; @Directive({ selector: 'angular-slickgrid', // 和组件选择器一致,自动应用 standalone: true // Angular 14+可配置为 standalone 指令,低版本则声明到模块中 }) export class AngularSlickgridEventTypesDirective { // 为每个事件声明Output,指定输出参数类型 @Output() onSelectedRowsChanged = new EventEmitter<SlickGridEventMap['onSelectedRowsChanged']>(); @Output() onCellClick = new EventEmitter<SlickGridEventMap['onCellClick']>(); @Output() onSort = new EventEmitter<SlickGridEventMap['onSort']>(); // 其余事件对应Output依次声明 // 监听原生CustomEvent,拿到detail后直接emit给Output,仅做类型透传 @HostListener('onSelectedRowsChanged', ['$event.detail']) private handleSelectedRowsChanged(detail: SlickGridEventMap['onSelectedRowsChanged']) { this.onSelectedRowsChanged.emit(detail); } @HostListener('onCellClick', ['$event.detail']) private handleCellClick(detail: SlickGridEventMap['onCellClick']) { this.onCellClick.emit(detail); } @HostListener('onSort', ['$event.detail']) private handleSort(detail: SlickGridEventMap['onSort']) { this.onSort.emit(detail); } // 其余事件对应监听方法依次实现 }
- 将该指令导出到库的公共API,用户引入后即可沿用原来的使用方式,不需要做任何类型强转,
strictTemplates下也不会报错:
<angular-slickgrid gridId="grid28" [columnDefinitions]="columnDefinitions" [gridOptions]="gridOptions" [dataset]="dataset" (onSelectedRowsChanged)="handleOnSelectedRowsChanged($event.eventData, $event.args)"> </angular-slickgrid>
handleOnSelectedRowsChanged(event: any, args: OnSelectedRowsChangedEventArgs) { console.log(args); }
临时用户侧绕路方案
如果用户不想等待库更新,可直接在模板内做内联类型断言,不需要修改TS逻辑:
<angular-slickgrid gridId="grid28" [columnDefinitions]="columnDefinitions" [gridOptions]="gridOptions" [dataset]="dataset" (onSelectedRowsChanged)="handleOnSelectedRowsChanged(($event as CustomEvent).detail.eventData, ($event as CustomEvent).detail.args)"> </angular-slickgrid>
内容的提问来源于stack exchange,提问作者ghiscoding
相关产品推荐
相关产品推荐

