What is the purpose of bivarianceHack in TypeScript types?

后端 未结 1 1846
旧巷少年郎
旧巷少年郎 2020-12-15 16:59

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

@types/

相关标签:
1条回答
  • 2020-12-15 17:47

    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

    0 讨论(0)
提交回复
热议问题