question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Get type of runtime value

See original GitHub issue

Add .getType() to Object prototype, which will allow get real type of value in variable, just like C# do.

Proposed Changes

  • Create const TypeSymbol = Symbol("tst-reflect-type");,
  • for reflected classes generate Class[TypeSymbol] = getType<Class>()
  • inruntime package declare
Object.defineProperty(Object.prototype, "getType", {
    enumerable: false,
    value: () => function() { return this.constructor[TypeSymbol]; }
});

Notes

Example

const foo: any = new Class();
foo.getType(); // => Type.ctor = Class

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:12 (8 by maintainers)

github_iconTop GitHub Comments

1reaction
Hookynscommented, Feb 11, 2022

Done. Without extension of Object’s prototype.

@reflect() decorator needed just to say the transformer to include that type into metadata. It will not be needed after “include/exclude” configuration.

@reflect()
class A
{
}

@reflect()
class B
{
}
const a: any = new A();

const typeOfVarA = getType(a);
console.log(typeOfVarA.name); // > "A"

const typeOfA = getType<A>();
console.log(typeOfA.name, typeOfVarA.is(typeOfA), typeOfVarA == typeOfA); // > "A", true, true
const array: any = [new A(), new B()];

const typeOfArray = getType(array);
console.log(typeOfArray.isArray()); // > true

const arrayTypeArg = typeOfArray.getTypeArguments()[0];
console.log(arrayTypeArg.union); // > true
console.log(arrayTypeArg.types.map(arg => arg.name).join(", ")); // > "A, B"
const array2: any = [new A(), new B(), "string", true, false, { foo: "bar"}];

const typeOfArray2 = getType(array2);
console.log(typeOfArray2.isArray()); // > true

const arrayTypeArg2 = typeOfArray2.getTypeArguments()[0];
console.log(arrayTypeArg2.union); // > true
console.log(arrayTypeArg2.types.map(arg => arg.name).join(", ")); // > "A, B, string, boolean, Object"

console.log(arrayTypeArg2.types[4].getProperties().map(p => p.name + ":" + p.type.name)); // > [ "foo:string" ]
1reaction
rezonantcommented, Feb 6, 2022

A smaller point: Imagine there are two projects that do the same thing. Someone else (maybe making a serialization library or something) also decides to put getType() onto the Object prototype. What happens for users? Why is your getType() “more canonical” than someone else’s getType()? What if you want to use those two libraries together?

More importantly though, imagine your project becomes popular out on the web and then WHATWG decides to add a builtin getType() to Object, but they can’t because you modified the prototype and shipping that change in the browser will break all of these websites. This is literally what smooshgate was about (Mootools added Array.flatten, became popular, is now out there on websites that will never change, which forced the browser makers to go with Array.flat which is less than the ideal name for the method because Mootools decided they could just monkey patch any extra functionality they had directly onto the builtins). That’s what the article above is talking about- and it is a cautionary tale to framework designers in the ecosystem.

Monkeypatching methods onto built in types is short-sighted, will always be frowned upon, and has the real potential to cause problems for the ecosystem if your solution becomes popular. There’s so many other good options that bypass this entire problem too, it could be Type.getType(value) or getType(value) (as opposed to getType<T>()) or even getTypeFromValue(value).

I also have a lot of experience in C#, hell I’ve even implemented portions of the CLR in another life, it’s a great language and a great runtime. But what makes C# and the CLR great isn’t just that it has a convenient getType() method on the Object class.

It was bad practice because direct Object.prototype.getType change behavior of for…in, that’s why x.hasOwnProperty() should be used.

That’s a small (but important) detail at the time, but that is a very small reason compared to the larger reason of leaving the namespace on the builtin prototypes free for Ecmascript to define. You might ask, why don’t they just disable the ability to modify the builtin prototypes? That would preclude polyfills on already-standardized but not yet implemented features in the JS environment you are running in. It would also preclude Zone.js’ patching. And of course it would also break all the websites out there that already did it and that’s not really an option. But just because the option is there and the community has made this mistake before (again and again and again) does not mean we should walk carelessly into making that mistake yet again.

Here’s just a few references:

Read more comments on GitHub >

github_iconTop Results From Across the Web

Get the runtime type of a generic method parameter
Is there are any way to get the runtime type of an instance without using *.GetType() in this case, even for a null...
Read more >
Runtime Type Identification in Java - GeeksforGeeks
getClass() method is used to determine the type of object at run time. Return Type: Returns the Class objects that represent the runtime...
Read more >
Object.GetType Method (System) - Microsoft Learn
The following code example demonstrates that GetType returns the runtime type of the current instance.
Read more >
Get data type of runtime value? - SAP Community
What i want, at runtime i want to get the data type of entered value. for eg, if i enter value 3.4 -->...
Read more >
apex - How to get the Runtime-Type of an Object dynamically ...
Say you have a mixed List<object> and want to process each element according to it's real type.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found