#lo hago yo?

1 messages · Page 1 of 1 (latest)

umbral niche
#

aquí mismo te contesto

small topaz
#

okey

umbral niche
#

puedes explicar desde el inicio qué intentas hacer? incluyendo código

small topaz
#

vale, el concepto lo medio entiendo, pero el problema creo que es ese, que ts no puede obtener el valor en tiempo real y se queda con eso, boolean

small topaz
#

vale, tengo una clase que tiene una propiedad requiredAccount de tipo boolean y por defecto false.

Con una función llamada requireAccount(val: boolean) es como le doy valor a esa propiedad.
Ahora, hay otra función en la clase que se encarga de establecer la función que se va a ejecutar una vez el comando se use, setFunction

Le tienes que pasar un callback en el que la función te da como valores un objeto con varias cosas útiles y entre una de esas está la propiedad account como se puede ver en la primera imagen. El valor que tiene account depende del valor de requiredAccount (true | false) y quiero que si es true, el tipo de dato de account sea AccountData y en su defecto que sea AccountData | null

#
// d.ts file
// SubCommand
export type SubCommandAction<L extends boolean> =
(options: SubCommandActionOptions<L>) => void;

interface SubCommandActionOptions<L extends boolean> {
    client: DiscordClient;
    interaction: ChatInputCommandInteraction;
    command_options: CommandOptions;
    command: Command | SubCommand;
    language: languages;
    account: L extends true ? AccountData : AccountData | null;
}
// class SubCommand
export class SubCommand extends SlashCommandSubcommandBuilder {
    public execute: SubCommandAction<boolean> = () => {};
    public disabled: boolean = false;
    public admin: boolean = false;
    public version: string = "0.0.0";
    public requiredAccount: boolean = false;

    // aún no consigue inferir los datos
    setFunction(callback: SubCommandAction<boolean>): this
    setFunction(callback: SubCommandAction<true>): this
    setFunction(callback: SubCommandAction<false>): this
    setFunction<T extends this["requiredAccount"]>(callback: SubCommandAction<T>): this {
        this.execute = callback;
        return this;
    }

    setDisable(value: boolean): this {
        this.disabled = value;
        return this;
    }

    setAdmin(value: boolean): this {
        this.admin = value;
        return this;
    }

    setVersion(value: string): this {
        this.version = value;
        return this;
    }

    requireAccount(value: boolean): this {
        this.requiredAccount = value;
        return this;
    }
   }
umbral niche
#

ya veo, ahora lo entiendo

#

lo que tienes que hacer genérico es tu clase

small topaz
#

como hago eso?

umbral niche
#

Las clases también pueden ser genéricas:

export class SubCommand<T extends boolean = false> extends SlashCommandSubcommandBuilder {
  ...
}
#

creo que es así

small topaz
#

pero eso no m obliga que al instanciar la clase tenga que hacer:

const command = new SubCommand<true>()
#

?

zenith dawn
#

No

#

Si no le pasas el genérico, es false

small topaz
#

claro, xro si quiero que sea true tengo que hacerlo como puse arriba, no?

umbral niche
#

ahora lo que falta es arreglar los overloads de tu método, debes retornar this pero la versión de this que existiría si le hubieras pasado true o false, dependiendo el caso

#

no recuerdo como se hace, dame un minuto

small topaz
#

dale

zenith dawn
#

Si no me equivoco, si haces que el valor que recibe por parámetros el método requireAccount sea de ese tipo genérico T, y le pasas true, TypeScript será capaz de inferir el valor que tiene el genérico

#

Igual que @umbral niche confirme

umbral niche
#

creo que no, porque espera poder llamar el método "modificado" después de setear su callback

#

el nuevo objeto que se retorna, que es el this debe tener el genérico en true

small topaz
#

y que hago con T?

umbral niche
#

Según yo lo que deberías retornar entonces en tus overloads es algo así:

setFunction(callback: SubCommandAction<true>): SubCommand<true>;
setFunction(callback: SubCommandAction<false>): SubCommand<false>;
setFunction(callback: SubCommandAction<boolean>): SubCommand<boolean> {
  // aquí el cuerpo de tu método "real"
}
#

Si, SubCommand se refiere a la misma clase a la que pertenece ese método

#

aunque tal vez debas escribirlo como this as SubCommand<true>

small topaz
#

y d la otra manera solo m hace el SubCommand<true>

umbral niche
#

puedes poner aquí la clase "SubCommandAction" ?

small topaz
#

que por cierto, la T entonces de que sirve?

small topaz
#
export type SubCommandAction<L extends boolean> =
(options: SubCommandActionOptions<L>) => void;

interface SubCommandActionOptions<L extends boolean> {
    client: DiscordClient;
    interaction: ChatInputCommandInteraction;
    command_options: CommandOptions;
    command: Command | SubCommand;
    language: languages;
    account: L extends true ? AccountData : AccountData | null;
}
umbral niche
#

Hmm, déjame pensar cómo juntarlo todo

small topaz
#

dale

umbral niche
#

Ok, creo que ya lo tengo, dame unos minutos más y traigo la solución

#

o al menos una indicación de por dónde avanzar

small topaz
small topaz
#

@umbral niche

#
export class SubCommand<T extends boolean = false> extends SlashCommandSubcommandBuilder {
    public execute: SubCommandAction<boolean> = () => {};
    public disabled: boolean = false;
    public admin: boolean = false;
    public version: string = "0.0.0";
    public requiredAccount: boolean = false;

    // aún no consigue inferir los datos
    setFunction(callback: SubCommandAction<T>): SubCommand<T> {
        this.execute = callback;
        return this;
    }

    setDisable(value: boolean): this {
        this.disabled = value;
        return this;
    }

    setAdmin(value: boolean): this {
        this.admin = value;
        return this;
    }

    setVersion(value: string): this {
        this.version = value;
        return this;
    }

    requireAccount<R extends boolean>(value: R): SubCommand<R> {
        this.requiredAccount = value;

        return this;
    }
}
#

aunque la implementación funciona, xro m da ese error

#

aunque si le pongo esto parece que la implementación funciona y se elimina el error

#

dios vaya salvado m has hecho t lo juro

#

muchísimas gracias d verdad

umbral niche
#

Creo que hay algo que se tiene que cambiar, el valor de requiredAccount debería ser T también, pero para eso debes de dejar de setearlo como false por default, tienes que setearlo en el constructor

umbral niche
small topaz
umbral niche
#

es verdad, entonces ya no le muevas xD

#

aunque

#

te recomiendo hacer el cambio que te dije, porque si lo dejas así, puedes instanciar la clase pasándole <true> y el valor en realidad sería false, por lo que los types te estarían mintiendo

small topaz
#

Type 'boolean' is not assignable to type 'T'.
'boolean' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'boolean'

umbral niche
#

Hmm el problema es el valor por default

#

no sé cómo hacer que te permita setear un valor por default, porque según yo no hay manera de impedir que pases manualmente <true> al momento de instanciar la clase

small topaz
umbral niche
#

Hmm bueno creo que así como está no deberías tener mayor problema

small topaz
#

no puedo darte mucho, xro t di mención en mi código sobre la implementación, muchísimas gracias bro 🫂

zenith dawn
#

Yo había hecho un ejemplo muy pequeño pero no sé si era lo que querías o algo así

umbral niche
#

No hay de qué, si me mencionas me pones como DeadOce4n,

small topaz
umbral niche
small topaz
zenith dawn
#

en lugar de cambiar el tipo de account, cambie el del output del callback que se le pasa a setFunction

#

pero es lo mismo, creo que se entiende la idea