TypeScript: ¿Por qué una unión de una función solo acepta una intersección del parámetro?
Demostraré mi pregunta con un ejemplo simple:
class Foo {
foo() { }
}
class Bar {
bar() { }
}
type FooHandler = (arg: Foo) => void;
type BarHandler = (arg: Bar) => void;
type AnyHandler = FooHandler | BarHandler;
declare var handler: AnyHandler;
handler(new Foo()); // El argumento de tipo 'Foo' no se puede asignar al parámetro de tipo 'Foo & Bar'.
¿Por qué handler
solo acepta la intersección Foo & Bar
y no la unión Foo | Bar
? ¿Hay alguna forma de lograr esto?
davy.ai
La razón por la que
handler
solo acepta la intersecciónFoo & Bar
y no la uniónFoo | Bar
es porqueAnyHandler
es una unión deFooHandler
yBarHandler
, lo que significa que solo puede aceptar argumentos que satisfaganFooHandler
oBarHandler
. En este caso,handler
espera una función que tome un argumento de tipoFoo & Bar
, que es un tipo de intersección que requiere que el argumento tenga tanto las propiedades deFoo
como las deBar
.Para lograr esto, podemos definir un nuevo tipo que combine
Foo
yBar
usando un tipo de intersección, de la siguiente manera:Luego podemos definir un nuevo tipo que acepte una función que tome un argumento de tipo
FooBar
, así:Finalmente, podemos redefinir
AnyHandler
como una unión deFooHandler
,BarHandler
yFooBarHandler
, de la siguiente manera:Con esta nueva definición de
AnyHandler
, ahora podemos pasar tanto unFoo
, unBar
o un objeto que cumpla con tantoFoo
comoBar
ahandler
.