TypeScript 类型中 bivarianceHack 的目的是什么? [英] What is the purpose of bivarianceHack in TypeScript types?

查看:72
本文介绍了TypeScript 类型中 bivarianceHack 的目的是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在阅读 React 的 TypeScript 类型时,我看到了这种模式的一些用法,包括 bivarianceHack() 函数声明:

@types/react/index.d.ts

type EventHandler>= { bivarianceHack(event: E): void }["bivarianceHack"];

虽然我找到了 其他实例 正在使用此模式,因此它似乎不是特定于 React 的模式.

为什么使用这种模式而不是 (event: E) =>无效?

解决方案

这与 strictfunctionTypes 选项下的函数兼容性有关.在此选项下,如果参数是派生类型,则不能将其传递给将传入基类参数的函数.例如:

class Animal { private x:undefined }类狗扩展动物 { 私人 d:未定义}type EventHandler=(事件:E)=>空白让 o: EventHandler= (o: 狗) =>{ }//在strictFunctionTypes 下失败

然而,对于严格的函数类型有一个警告,在 PR 中有说明><块引用>

更严格的检查适用于所有函数类型,除了源自方法或构造函数声明的那些.专门排除方法以确保通用类和接口(例如 Array)继续主要协变相关.严格检查方法的影响将是一个更大的突破性变化,因为大量泛型类型将变得不变(即便如此,我们可能会继续探索这种更严格的模式).

强调

所以,hack 的作用是允许 EventHandler 的双变量行为,即使在 strictFunctionTypes 下.由于事件处理程序的签名将在方法声明中有其来源,因此不会受到更严格的函数检查.

type BivariantEventHandler= { bivarianceHack(event: E): void }["bivarianceHack"];让 o2: BivariantEventHandler= (o: 狗) =>{ }//在strictFunctionTypes 下仍然可以

游乐场链接

While reading through the TypeScript types for React, I saw a few usages of this pattern involving a bivarianceHack() function declaration:

@types/react/index.d.ts

type EventHandler<E extends SyntheticEvent<any>> = { bivarianceHack(event: E): void }["bivarianceHack"];

Searching didn't lead me to any documentation on why this particular pattern was used, although I've found other instances of this pattern in use so it seems it's not a React-specific pattern.

Why is this pattern being used rather than (event: E) => void?

解决方案

This has to do with function compatibility under the strictfunctionTypes option. Under this option if the argument is of a derived type you can't pass it to a function that will pass in a base class argument. For example:

class Animal { private x:undefined }
class Dog extends Animal { private d: undefined }

type EventHandler<E extends Animal> = (event: E) => void

let o: EventHandler<Animal> = (o: Dog) => { } // fails under strictFunctionTypes

There is however a caveat to strict function type, stated in the PR

The stricter checking applies to all function types, except those originating in method or constructor declarations. Methods are excluded specifically to ensure generic classes and interfaces (such as Array<T>) continue to mostly relate covariantly. The impact of strictly checking methods would be a much bigger breaking change as a large number of generic types would become invariant (even so, we may continue to explore this stricter mode).

Emphasis added

So the role of the hack is to allow the bivariant behavior of EventHandler even under strictFunctionTypes. Since the signature of the event handler will have its source in a method declaration it will not be subject to the stricter function checks.

type BivariantEventHandler<E extends Animal> = { bivarianceHack(event: E): void }["bivarianceHack"];
let o2: BivariantEventHandler<Animal> = (o: Dog) => { } // still ok  under strictFunctionTypes 

Playground link

这篇关于TypeScript 类型中 bivarianceHack 的目的是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆