Какова цель bivarianceHack в типах TypeScript? - PullRequest
0 голосов
/ 05 октября 2018

При чтении типов TypeScript для React я видел несколько примеров использования этого шаблона с объявлением функции bivarianceHack():

@types/react/index.d.ts

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

Поиск не привел меня к какой-либо документации о том, почему этот конкретный шаблон использовался, хотя я обнаружил другие экземпляры этого шаблона в использованиитак что кажется, что это не специфичный для React шаблон.

Почему этот шаблон используется, а не (event: E) => void?

1 Ответ

0 голосов
/ 05 октября 2018

Это связано с совместимостью функций в опции strictfunctionTypes.Под этой опцией, если аргумент имеет производный тип, вы не можете передать его функции, которая передаст аргумент базового класса.Например:

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 strictFunctionTyes

Тем не менее, существует оговорка к строгому типу функции, указанному в PR

Более строгая проверка применяется ко всем типам функций, за исключением тех, которые исходят из объявлений метода или конструктора .Методы исключены специально, чтобы гарантировать, что универсальные классы и интерфейсы (такие как Array) по-прежнему в основном связаны ковариантно.Результатом строгой проверки методов будет гораздо большее критическое изменение, поскольку большое количество универсальных типов станет инвариантным (даже в этом случае мы можем продолжить изучение этого более строгого режима).

Акцентдобавлено

Таким образом, роль хака состоит в том, чтобы разрешить бивариантное поведение EventHandler даже при strictFunctionTypes.Поскольку подпись обработчика события будет иметь свой источник в объявлении метода, она не будет подвергаться более строгим проверкам функций.

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

Playground link

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...