#Executing a function from a string using dynamic import

155 messages · Page 1 of 1 (latest)

lapis knoll
#

Hello, how can I execute whatever is parameter, for example, I have a const in ../constants/support called debug, how can I make execute like support.debug, but instead of debug use a string that I'm passing

const support = await import("../constants/support");
support.Function(parameter);```
lapis knoll
#

!resolve

#

Actually, my bad, my idea was to instead return something else in the function but forgot I won't still be able to call it

#

!reopen

odd flax
#

Do you mean something like

const level = "debug";

const support = await import("../constants/support");

support[level](parameter);
lapis knoll
#

I'll test out in a couple of minutes

#

Actually, my bad, no

#

I have a parameter

#

For example

const parameter = "debug";
#

And I need to run the parameter via support.

left dust
#

@lapis knoll while what you're trying to do might work, I would not recommend it

#

running code from a string is not ideal

#

also the fact the code is a strig doesn't give you any type checking, etc.

lapis knoll
#

Hey, so I made a list string[], if the parameter is not in the array, then error

lapis knoll
#

Ok well, so if debug is not in a list

const list = ["notdebug", "a"];```
then error, if notdebug is the parameter, run notdebug
lapis knoll
#

!helper

topaz grove
#

what

lapis knoll
topaz grove
lapis knoll
#

No index signature with a parameter of type 'string' was found on type 'typeof import .....

topaz grove
#

well obviously parameter is a string

#

thus its not safe

lapis knoll
#

In the const file I'm using EmbedBuilder class and cannot be a string

topaz grove
#

many ways to fix

lapis knoll
#

Well do you have any ideas?

topaz grove
#

one way would be to use as any there 🧠

#

other proper way would to use a type guard function

topaz grove
lapis knoll
#

Probably I can convert the const to a function, but would that still work the same?

topaz grove
#

what const

lapis knoll
#

I mean this works

    const support = await import("../constants/support") as any;
    [support[parameter]()]```
just haven't executed the code to test
topaz grove
#

no not that as any

#

parameter as any

lapis knoll
lapis knoll
# topaz grove parameter as any

Well Element implicitly has an 'any' type because expression of type 'any' can't be used to index type 'typeof import ....

topaz grove
#

its already a function?

lapis knoll
#

Oh, then my bad

lapis knoll
topaz grove
#

btw does support file export the same function signatures but different functionalities?

lapis knoll
#

Ah well if parameter === "notdebug", then it would run export const notdebug = () => {}

#

But still, is it alright to make the import as any?

topaz grove
topaz grove
lapis knoll
#

Well do you have any suggestions on how would I make it not any? I mean (support[parameter] as String) thought going to be fine but no

topaz grove
#

would help marginally

lapis knoll
#

Currently confused, I guess you mean is my function has an any type? If so, no

topaz grove
lapis knoll
#

I got export const debug = (guild: Guild) => {}, so I did support[parameter as any](interaction.guild)

lapis knoll
#

Would this be my solution?

    const support = await import("../constants/support") as string;
support[parameter as string](interaction.guild)```

if so, I got 2 errors, first one VSC tells me to do `import("...") as unknown as string`, second `Element implicitly has an 'any' type because index expression is not of type 'number'.` on parameter, but I've did `let parameter: string` also
lapis knoll
#

!helper

static sinew
#

whats the problem now

#

are you asking about your solution?

#

or are you looking for a solution to the original problem

lapis knoll
#

Currently both, but I guess the best solution is my current solution, but it needs fixing

topaz grove
#

@lapis knoll is this someone elses code base

lapis knoll
#

What do you mean?

topaz grove
#

did you write the entire code

#

of the project or mo

lapis knoll
#

Yes I did the entire code, most I did, like 25% my friend

#

Why?

topaz grove
#

how do you usually fix ts errors

lapis knoll
#

Well such as?

topaz grove
#

variable 's' is type unknown

lapis knoll
#

Well in most solutions I would just make sure the string is required, but I've never used dynamic imports

#

Oh well in this example making the const string worked, but import is not assignable tho, basically the same thing

topaz grove
#

this isn't a 100% correct representation but you can think of a module as an object

#

so await import("...") would be an object

#

if you are doing support[parameter as string], it has the same effect as SomeType[string] and that will be the union of all possible members

#

but there are two catches

#

(typeof support)[string] is not guaranteed to be valid since string is not limited to keyof support

#

so

#

lets say you convince TS that it is using as any

#

support[parameter as any]

#

the value of that will be the union of all valid members

#

if one of the members are different from another, it will be tricky for you to call

#

or, you can ignore this using // @ts-ignore and come back later

lapis knoll
#

Well parameter doesn't currently matter, because if you even make the import as any, it would work, but not ideal, so if I would need to make the import as a type which I currently don't know, so I'm here

topaz grove
#

well, i suggest making a typeguard

#

for parameter

#

when starting out typescript it can be hard

#

and often times somethings are obvious while others need more understanding of the comiler and language itself to fully comprehend

#

its good that you are trying to get things right but right now, its a little hard for you to do that

#

you might end up in a rabbit hole and never finish your project

#

so, try focus on making it work. this won't be your last project anyway, so at least show that it works before realising what you can do better

lapis knoll
#

Well parameter is string by

let parameter: string = interaction.options.getString("parameter", true); // could return anything, such as "notdebug"```
using let because I've made
```ts
if (parameter.includes("/"))
  parameter = parameter.replace("/", "_");```
But the error is happening on import, because it cannot be a typeof string, so I'm here asking, what should it be?
topaz grove
#

do you know what the parameter can be

#

actually, whats the most likely string it can be

lapis knoll
#

Well d.js also has options when calling an interaction with slash commands in my example, so getString is
public getString(name: string, required: true): string;

topaz grove
#

no like

#

when the code actually runs support[parameter]

#

what is parameter

#

most likely going to be

#

im trying to help you monkey patch this

lapis knoll
#

It could be anything that users can type, if the string is notdebug in the parameter, then I would simply need support.notdebug()

topaz grove
#

what if user does

#

asdf

#

its gonna call

#

support.asdf()

#

and your bot will crash because undefined is not a function

lapis knoll
#

Well if asdf is in a string[], then yes

topaz grove
#

ok, what is that string[]

#

show

lapis knoll
#
const list = ["notdebug", "somethingrandom"];
if (!list.includes(parameter))
  return throw new Error("literally an example");```
#

I'm not actually using throw, just returning an interaction.reply

topaz grove
#
const list = ["notdebug", "somethingrandom"] as const;
type ValidMethod = (typeof list)[number];
function isValidMethod(method: string): method is ValidMethod {
  return list.includes(method);
}
lapis knoll
#

Right, but Argument of type 'T' is not assignable to parameter of type "'notdebug ... and T cannot be used as a type in a value

topaz grove
#

oh crap

#

there

#

read this

lapis knoll
#

Well I did

function isValidFunction(method: string): method is ValidMethod {
  return list.includes(method);
}``` removing the <>, but now method in the .includes is somehow not assingable to `"notdebug" | "somethingrandom"'`
topaz grove
#

where

topaz grove
#

oh um, wow typescript got better

#

change the code to this

#
type ValidMethod = "notdebug" | "somethingrandom";
const list = ["notdebug", "somethingrandom"] satisfies ValidMethod[];
function isValidMethod(method: string): method is ValidMethod {
  return list.includes(method);
}
#

basically, they improved the type system of builtins i think

#

correct me if im wrong, others

#

anyway, this way list is string[] and the code should work

lapis knoll
#

That didn't work, but I'm going to change the list too, when going into reviewing, also VSC formatting making me do this ]satisfies

topaz grove
#

whats your ts version

#

wdym by didn't work

lapis knoll
#

Same error, TS 4.9.5

topaz grove
#

oh myb

#

const list: string[] = ["notdebug", "somethingrandom"] satisfies ValidMethod[];

#

isValidFunction will help you narrow down parameter to either of those strings

#

and typescript won't complain about doing support[parameter]

lapis knoll
#

Unfortunatly it does complain about ^

Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'typeof ...
No index signature with a parameter of type 'string' was found on type 'typeof ...```
topaz grove
#

@lapis knoll whats the code

#

oh wait

#

what

#

where

#

whats the code

lapis knoll
#

on support[parameter]

topaz grove
#

whats support

lapis knoll
#
const list: string[] = ["notdebug", "somethingrandom"]satisfies ValidMethod[];
type ValidMethod = "notdebug" | "somethingrandom";
function isValidMethod(method: string): method is ValidMethod {
  return list.includes(method);
}

if (!isValidMethod(parameter))
  return interaction.reply(...);

if (parameter.includes("/"))
  parameter = parameter.replace("/", "_");

const support = await import("../constants/support");
....... support[parameter]() ......```
topaz grove
#

no no you do it like

#

if (isValidMethod(parameter)) {
supportparameter
}

lapis knoll
#

That does nothing new, basically just remove the ! and makes the code switch places, tried it, same error on support[parameter]

topaz grove
#

its going to help you catch bugs later anyway

#

how are you exporting the functions btw

#

in the support file

topaz grove
#

huh, it should work then

#

something's not right

#

works on my machine ™️

lapis knoll
#

Using ES2022 if matters, anything else I can provide

lapis knoll
#

So, anyone got some suggestions?