Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do Typescript generics use type erasure to implement generics?

Meaning you cannot use something like this?

class Helpers
{
    static ObjectAs<T>(val: any): T {
        if (!(val instanceof T)) {
            return null;
        }

        return <T>val;
    }
}

Any workaround to get the underlying type of the generic declaration?

Update 1:

As Ryan Cavanaugh mentioned, when compiled, the whole type system is erased, more like Java's implementation of Generics. I believe .Net implementation of Generics to preserve type information in the compiled code is better than Java. However, I cannot help but wonder, why is not possible to permit full runtime introspection of generic types and generic type parameters in TypeScript? Why designers of TypeScript decided to remove all generic type information at runtime?

The following TypeScript code:

function As<T>(n: any): T {
    if (n instanceof T) {
        return n;
    } else {
        return null;
    }
}

var obj: Object = 1;
var x = As<number>(obj);

Could be translated to this JavaScript code:

function As(n, T) {
    if (n instanceof T) {
        return n;
    } else {
        return null;
    }
}

var obj = 1;
var x = As(obj, Number);

Preserving the type information at runtime and compatibility with the js code!

Update 2: I've posted the issue on CodePlex, hoping to get more from TypeScript people https://typescript.codeplex.com/discussions/550262

like image 785
Kamyar Nazeri Avatar asked Jun 28 '14 18:06

Kamyar Nazeri


People also ask

How do generics work in TypeScript?

Generics are to types what values are to function arguments — they are a way to tell our components (functions, classes, or interfaces) what type we want to use when we call it, just like how we tell a function what values to use as arguments when we call it.

What is type erasure in TypeScript?

Type erasure is quite simply when all the types get removed from the TypeScript code as it is transpiled to JavaScript. The types you use in TypeScript can't be inspected at run-time, when JavaScript is being executed. The types are only accessible during the compilation/transpilation step.

Is reified generics and type erased generics are same?

The whole point is that reified generics have support in the compiler for preserving type information, whereas type erased generics don't. AFAIK, the whole point of having type erasure in the first place was to enable backwards compatibility (e.g. lower versioned JVMs could still understand generic classes).

Does TypeScript support generics?

TypeScript fully supports generics as a way to introduce type-safety into components that accept arguments and return values whose type will be indeterminate until they are consumed later in your code.


1 Answers

The type system is wholly erased. You can see this in the generated code for any generic function.

That said, for classes, there's still some runtime information left. You could write this:

class A { }
class B { }
function As<T>(n: any, type: { new(...args: any[]): T }): T {
    if(n instanceof type) {
        return n;
    } else {
        return null;
    }
}

var x = new A();
var y = new B();
console.log(As(x, A));
console.log(As(x, B));
like image 60
Ryan Cavanaugh Avatar answered Sep 24 '22 17:09

Ryan Cavanaugh