#lo hago yo?
1 messages · Page 1 of 1 (latest)
okey
puedes explicar desde el inicio qué intentas hacer? incluyendo código
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
okey
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;
}
}
como hago eso?
Las clases también pueden ser genéricas:
export class SubCommand<T extends boolean = false> extends SlashCommandSubcommandBuilder {
...
}
creo que es así
pero eso no m obliga que al instanciar la clase tenga que hacer:
const command = new SubCommand<true>()
?
claro, xro si quiero que sea true tengo que hacerlo como puse arriba, no?
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
dale
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
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
y que hago con T?
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>
y d la otra manera solo m hace el SubCommand<true>
puedes poner aquí la clase "SubCommandAction" ?
que por cierto, la T entonces de que sirve?
es una interfaz, pero sí
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;
}
Hmm, déjame pensar cómo juntarlo todo
dale
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
dale, muchas gracias x el esfuerzo
The Playground lets you write TypeScript or JavaScript online in a safe and sharable way.
ya está, pasa el mouse encima de opts.account para que veas los types
En la instancia llamada publicSubcommand se resuelve a any, porque no copié la definición de AccountData
pero en teoría ese código debería funcionar ya en tu proyecto
voy a ver la implementación, dame unos minutos
@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
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
hmm, voy a ver
nooo, esto es incorrecto porque estás expandiendo el type hacia boolean, y ya no sabrás si es true o false
hm?, está funcionando con esa implementación
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
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'
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
bueno, no t calientes mucho con la cabeza con eso, funcionar funciona como debería
Hmm bueno creo que así como está no deberías tener mayor problema
no puedo darte mucho, xro t di mención en mi código sobre la implementación, muchísimas gracias bro 🫂
Yo había hecho un ejemplo muy pequeño pero no sé si era lo que querías o algo así
pásalo a ver x si acaso
No hay de qué, si me mencionas me pones como DeadOce4n,
igual lo dejo acá por si acaso te sirve... es muy parecido a lo que hizo @umbral niche
The Playground lets you write TypeScript or JavaScript online in a safe and sharable way.
así t puse, t llamas igual en github?
Si
espérate que d paso t sigo