#Get module from prototype

74 messages ยท Page 1 of 1 (latest)

charred fox
#

Is there a way to get the module(name) a given prototype was declared in?
E.g.

let prototype = MyType.prototype
let declaringModule = getDeclaringModule(prototype); // how would i do this
dry pasture
#

no such data is maintained, decorators might let you do that though

charred fox
#

bruh why is there so little reflection in ts

cobalt goblet
charred fox
#

why not

cobalt goblet
#

also there is actually a lot of reflection

charred fox
#

for a lot of stuff

cobalt goblet
#

getOwnPropertyDescriptors

#

.prototype, .constructor, getPrototypeOf, Proxy

charred fox
#

thats not a ton but its nice yeah

cobalt goblet
#

that is a ton

charred fox
#

but it would be nice if ts retained declared types and modules

cobalt goblet
#

like compared to c# what is it missing

charred fox
#

types

cobalt goblet
#

typescripts goal is to not exist at runtime

charred fox
#

the prototypes of types can be referenced as runtime

#

well that sucks

cobalt goblet
#

types dont exist in js

charred fox
#

prototypes

#
  • classes
#

do

cobalt goblet
#

prototypes are objects, classes are classes

charred fox
#

func(MyClass) passes the prototype of instances of MyClass to the function

#

if im not stupid

cobalt goblet
#

nope

#

it passes the class

#

the prototype is in MyClass.prototype

charred fox
#

even better then

#

also have the class

#

so theres enoguh type related stuff to have type retention as metadata

cobalt goblet
#

theoretically yes

#

realistically it's difficult to figure out a nice way to do this

charred fox
#

ig

cobalt goblet
#

it's easy enough to force yourself to annotate the correct types manually though

#

(as in, emit an error if they're missing)

#

well idk actually

#

idk if esquery is powerful enough

charred fox
#

for this specifically tho i want to get the module of any class passed

#

so i cant annotate every class

#

becasuse some arent from my code

cobalt goblet
#

what do u need the module for anyway

charred fox
#

differentiating class names

#

like nsamespace

#

but automated

cobalt goblet
#

but why do you need to do that

charred fox
#

idk it seems nice

cobalt goblet
#

if you can compare the class objects directly

charred fox
#

nah im getting the name as a string

#

but prefereably id want to prefix the name with the module

cobalt goblet
#

but why o.o

charred fox
#

for uniqueness in the map

#

if i have @discordjs.Client and @someothermodule.Client i dont want them to conflict

#

also doesnt Node print the declaring module name of a class in errors and stuff?

desert comet
#

this might seem a bit weird but you could use the class objects themselves as keys in your Map:

wanton mantleBOT
#
mkantor#0

Preview:```ts
type Constructor = new (...args: never[]) => unknown

class Foo {
isFoo = true
}
class Bar {
isBar = true
}

namespace SomeOtherModule {
export class Foo {
isADifferentFoo = true
}
}

const x = new Map<Constructor, {}>([
[Foo, new Foo()],
[Bar, new Bar()],
...```

charred fox
#

yeah true but i want them to optionally be accessible by a specific name too

#

if you have multiple instances

#

idk

#

this works ig

desert comet
#

another option is to give every class that wants to participate in this scheme a name: string property and write whatever you want there. it won't be as automagic as reflection but you can include a prefix to identify the module or whatever yourself

charred fox
#

yeah id probably do smth like that with decorators if i could but i want to do this for any class

#

from other modules too

desert comet
#

gotcha

cobalt goblet
#

its easy enough to get module path tbh

#

put a new method on object that throws an exception

#

class.method()

#

or not, since the class code wouldn't be in the stack trace

desert comet
#

you could use something from import.meta i think

#

assuming ESM

#

but anything like this would still require modifying the class definition, which it sounds like orbyfied doesn't want

desert comet
cobalt goblet
desert comet
#

i got it. use Class.toString() as the keys. classes with exactly the same source code will collide, but, i mean, structural typing and all ๐ŸšŽ