Tengo la siguiente firma de función:
const renderMessage = <T extends A | B > ( a: T, b: Map<T, Array<string>>, c: T, ) => {Mi problema es que puedo llamar a esta función de la siguiente manera:
type A = "A" | "B" type B = "Z" | "Y" let myA: A = "A" let myB: B = "Z" let myAMap: Map<A,Array<string>> = new Map(...) let myBMap: Map<B,Array<string>> = new Map(...) renderMessage(myA, myBMap, myA) // I want error here renderMessage(myB, myAMap, my B) // I want error here La razón para poder hacer esto se explica aquí . Si entendí correctamente, la estructura de mi objeto Map no cambia en función de que T sea A o B, por lo que el mecanografiado no se quejará. Sin embargo, estoy luchando para descubrir cómo hacer cumplir esto.
EDITAR
Son tipos y no clases. Ver enlace del patio de recreo
El tipo T es demasiado ambiguo para la inferencia de TypeScript. Se resuelve en el tipo más estrecho que satisface toda la firma: A | B
Supongo que solo tienes que proporcionarlo tú mismo entre paréntesis angulares:
La razón para tener diferentes clases, A y B, debería ser si un tipo de instancia debe contener datos estructurados de manera diferente a la otra, o si un tipo de instancia debe tener métodos diferentes. Si los datos están estructurados de la misma manera y los métodos son todos iguales, entonces no debería haber clases separadas.
Si distingue A y B de alguna manera, el error surgirá como se desea:
class A{ x = 'x' } class B{ y = 'g' } const renderMessage = <T extends A | B > ( a: T, b: Map<T, Array<string>>, c: T, ) => { } let myA: A = new A() let myB: B = new B() let myAMap: Map<A,Array<string>> = new Map(...) let myBMap: Map<B,Array<string>> = new Map(...) renderMessage(myA, myBMap, myA) // I want error here renderMessage(myB, myAMap, myB) // I want error here