TypeScript依赖类型和函数双方差

2021-01-28 22:11:05

TypeScript之所以不完善,部分原因是希望避免强迫程序员编写没有运行时效果的强制类型转换只是为了满足类型检查器。这段代码来自他们关于声音不健全的文档:

枚举EventType {鼠标,键盘,}接口事件{时间戳:数字;}接口MyMouseEvent扩展了事件{x:数字; y:数字;}接口MyKeyEvent扩展了事件{keyCode:数字;}函数listenEvent(eventType:EventType,处理程序:(n:Event)=> void){/ * ... * /} //不正确,但有用且commonlistenEvent(EventType.Mouse,(e:MyMouseEvent)=> console.log(ex +"," + ey)); //如果存在健全性listenEvent(EventType.Mouse,(e:事件)=> console.log((e作为MyMouseEvent).x +"," +(e作为MyMouseEvent).y))); listenEvent(EventType.Mouse,((e:MyMouseEvent)= > console.log(ex +"," + ey))as(e:Event)=> void); //仍然不允许(清除错误)。为完全不兼容的类型实施类型安全性listenEvent(EventType.Mouse,(e:number)=> console.log(e));

但是,TypeScript现在支持受限的依赖类型概念,因此激励性示例不再是问题:

//假设EventType,Event,MyMouseEvent和MyKeyEvent为上述类型GenericEvent< E扩展了EventType> = E扩展EventType.Mouse吗? MyMouseEvent:MyKeyEventfunction listenEvent< E扩展了EventType>(eventType:E,handler:(n:GenericEvent< E>)=> void):void; function listenEvent(eventType:EventType,handler:(n:GenericEvent< typeof eventType>)) => void):void {/ * ... * /} // ValidlistenEvent(EventType.Mouse,(e:MyMouseEvent)=> console.log(ex +"," + ey) ); // ValidlistenEvent(EventType.Keyboard,(e:MyKeyEvent)=> console.log(e.keyCode)); // InvalidlistenEvent(EventType.Mouse,(e:MyKeyEvent)=> console.log(e。 keyCode)); // InvalidlistenEvent(EventType.Mouse,(e:Event)=> console.log(ex +"," + ey));

依赖类型不能解决所有妨碍稳健性的可用性问题,但是它们消除了主要问题,因此应该更新库以利用依赖类型。