This project is read-only.

Can someone please explain typeof

Topics: General, Language Specification
Sep 13, 2013 at 2:16 PM
Can someone please explain "typeof" for me? I am having trouble understanding the difference between...

var b: A;


var b: typeof A;

How exactly is typeof to be used and for what senarios?
Sep 13, 2013 at 6:33 PM
The easiest way to understand typeof is that it represents the type of the supplied value. In other words, for all X, these two declarations are equivalent from a type perspective:
var p1 = X; // p1 infers its type from X
var p2: typeof X; // p2 has the same type as X and is identical to p1
This gets weird for classes, which create two different things that have the same name. When you define a class, a type name is defined that refers to the shape of an instance of that class. You also define a value of the same name that represents the constructor function object along with any static members. We casually refer to that second name as the "static" side of the class, and the type of that value is normally anonymous. typeof lets you grab that anonymous type.

class A {
    static x: number;
    y: string;

var instance = new A(); // instance: { y: string; }
var t1 = A; // t1: { x: number; new() => A; }
var t2: typeof A; // t2 is identical to t1
Finally, generics. It's very tempting to try to do this:
function create<T>() {
    var x: typeof T = /* ..???... */;
    return new x();
// Cannot possibly work because types are erased, but let's try anyway
var p = create<MyClass>();
This does not work because T is not a value, it's a type. Remember that typeof operates on values and produces types (somewhat confusingly, the exact opposite of what the C# typeof operator does). What you want to do instead is this (note that typeof is not needed):
function create<T>(ctor: { new (): T; }) {
    return new ctor();
var c = create<MyClass>(MyClass); // c: MyClass
The guidance on when to use typeof is: If you find yourself needing the type of a value that is otherwise anonymous, use it. Otherwise, don't worry about it.
Sep 15, 2013 at 1:32 PM
Use case one: When the static-side of a class needs to be passed to a function.
class Foo {
    static bar(){
function doClass(f:Foo){; // Error: Static member cannot be accessed off an instance variable

function doClassTwo(f:typeof Foo){; // okay
Use case two: When a module needs to be passed to a function
module foo {
    export function bar(){

// Error: Type reference cannot refer to container foo
function doModule(f: foo){;

// Okay
function doModuleTwo(f: typeof foo){;
Note that this is purely a compile-time rule enforced by TypeScript. In the compiled JavaScript a module is simply yet another variable, and hence can be referenced directly. Similarly, a class is just a function, and as we know, in JavaScript, functions are first class objects.

In fact all the following have identical behaviour at runtime:
TypeScript simply has a more rigorous approach - although I'm not entirely convinced about the need for this distinction.
Sep 16, 2013 at 1:54 PM
Thank you @RyanCavanaugh and @nabog. Both of your examples and explanations helped.