Typescript + GraphQL Dataloader más tipos estrictos utilizando genéricos o sobrecargas.
Estoy usando el dataloader de GraphQL y me gustaría hacer que mis tipos de retorno sean más estrictos en función de las claves que se pasen. ¿Cómo podría lograr esto? Intento débil a continuación. Sé por qué no funciona, pero no estoy seguro de qué arreglar. (El mismo código existe en el playground de ts [aquí].(https://www.typescriptlang.org/play?ssl=27&ssc=2&pln=1&pc=1#code/C4TwDgpgBAYgTgVwJbAHIEMC20C8UDk6YYANhPlAD4EBG6Adg+vgFCiSyIoDSEIAPABUM2KBAAewCPQAmAZ07I0WCAD4oeAN6NsALijCVAGihIZ++gkw0IcAL5tw0AILEyGgs9btoAISaMHvi+rCxI9FJwAGboAMbQ8EoAaugkCBAKmixQUESkEPqu+dlQdIyM+v7l6CwOLDIQsSTocNBN6HIKACLowOgAMgD26A1w-NwmSepZOSTDMgAUANZ8+twAlPpJtSwsUQj0scBIg-RQAOYQwEMjtkJiktLyiigiagvrUDNQAPQ-BgALJAKGSDDL0fDAKAAd0GcCWJhoCChKHwCmAAOg52GJAAtLioAg5NAMdBBBdpLYkLEoMBBlA5ADBtDaZioK1msdToykGBSldoRBpFAViAoAAyKAAN1S6QAdFASq1gAg4Gd6BAWT0+jdRvxEjw+EJVCYDcAUmkMgBtQQAXVUHx2ewORxOZ0w6HCHy+JVi3KhUS413mtg8l2DtzgjpyfygAHEkFLhRjeqzoDpoMCCHkyPgTKT2VdVWcfAymQgSDJ+VAimREcjTCiFLXoNQqkwcr7-bk3LgoIGlLrbHK5iMFtoVPpCL286ZzFAAIx2da7GP-BNJksA1MFjOmBT4MpMWcF5XF2lOMuDCtVmxQduBRU5P30ORQo+BPADlBDuAj+bjhmU4fswJhmPoABMy47DkQA))
“`ts
type FruitName = 'apple' | 'banana'
type FruitKey<tname extends="" fruitname=""> = {name: TName, id: number}
type Apple = 'A'
type Banana = 'B'
interface FruitValues {
apple: Apple
banana: Banana
}
declare class DataLoader<k, v=""> {
load(key: K): V
}
function getLoader<t extends="" fruitname="">() {
// Esto no funciona, pero es el objetivo: usar el genérico T para mostrar la relación entre la clave y el valor.
return new DataLoader<><t>, FruitValues[T]>()
}
function main() {
const fruitLoader = getLoader()
// Dado que el nombre es 'apple', el tipo de retorno debería ser Apple, pero es Apple | Banana
const apple = fruitLoader.load({name: 'apple', id: 1})
// Dado que el nombre es 'banana', el tipo de retorno debería ser Banana
const banana = fruitLoader.load({name: 'banana', id: 2})
}
“`</k,>
davy.ai
Para hacer que los tipos de retorno sean más estrictos en función de las claves que se pasan al usar el dataloader de GraphQL, los tipos genéricos para la clase DataLoader se pueden modificar de la siguiente manera:
En lugar de usar el tipo genérico para asegurarse de que la propiedad
T
para especificar el nombre de la fruta, se pasa como argumento a la funcióngetLoader
. La clase DataLoader ahora se define con dos tipos genéricos:K
extiende FruitKeyname
coincida con uno de los nombres de frutas, yV
es el tipo de valor del nombre de fruta correspondiente en la interfaz FruitValues.La función
getLoader
ahora devuelve la instancia apropiada de DataLoader según el nombre de la fruta pasado como argumento. El métodoload
puede ser llamado con un objeto FruitKey cuya propiedadname
coincida con la instancia correspondiente de DataLoader, y el tipo de retorno será el tipo de valor del nombre de fruta correspondiente en la interfaz FruitValues.