Typescript: Cannot access name of function or class in a type-safe way

Created on 19 Feb 2015  路  13Comments  路  Source: microsoft/TypeScript

The property name of function does not seem to be available in Typescript:

function foo() {鈥
foo.name; // 'foo'

error TS2339: Property 'name' does not exist on type '() => string'.

I can declare an interface but it requires a cast:

interface F {
    (...rest): any;
    name: string
}

(<F>foo).name;

Is there a better way? Shouldn't Typescript know about the predefined properties of functions?

While I'm at it, the same issue comes up with classes: the name of the constructor is the name of the class, so in plain Javascript you could get the name as above, but it does not work in Typescript:

class A { 鈥
A.name

error TS2339: Property 'name' does not exist on type 'typeof A'.

Here the above solution does not even work, since A is considered as the class, not the constructor function...

By Design

Most helpful comment

It is easy to fix.
Just declare name:

interface Function {
    name: string;
}

// Using it
function f(): string { return f.name; }

The 'name' property is part of ES6 that's why you don't see it in lib.d.ts.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name

I think it will be declared in lib.es6.d.ts and you need to use ES6 generation option.

All 13 comments

It is easy to fix.
Just declare name:

interface Function {
    name: string;
}

// Using it
function f(): string { return f.name; }

The 'name' property is part of ES6 that's why you don't see it in lib.d.ts.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name

I think it will be declared in lib.es6.d.ts and you need to use ES6 generation option.

Thanks for the quick answer, I didn't realize I could extend Function.

Indeed, compiling for ES6 works without any added declaration, and adding the interface declaration works for ES5. And it also gives access to the class name as A.name.

Interfaces can be extended.
If you think from the JS perspective , then it is obvious.
You always can add any property to the object.
Therefore TS allows you to add properties to the existing interface.

I have class that looks like this:

class Iterator {

    protected position: Position;

    constructor(position: Position) {
        this.position = position;
    }

    toString(): string {
        return this.constructor.name;
    }
}

When I compile, I get the following error:
2339 Property 'name' does not exist on type 'Function'.

I suspect you have put your code augmenting the Function interface in an external module so your attempted augmentation does not exist in the same scope as the original definition. You need to write the augmentation in a global scope and then reference it.

yes at the end of the file I wrote:

export = Iterator;

Could you point me to a way I should rewrite my code? Thank you so much for the support @danquirk

@wcandillon put your extensions in a .d.ts that exists in the global scope (where the existing Function definition from lib.d.ts is) and reference that. So:

ext.d.ts:

interface Function {
    name: string
}

iterator.ts:

/// <reference path='ext.d.ts'/>

class Iterator {

    protected position: Position;

    constructor(position: Position) {
        this.position = position;
    }

    toString(): string {
        return this.constructor.name;
    }
}

export = Iterator;

hi,
i have this function :

getContact():any {
this._contactService.getContacts().then((contacts: Contact[]) => this.contacts = contacts);
}

When i compile, I get the following error in gulp:
error TS2339 : Property 'then' does not exist on type 'void'

@yagobilel please post questions on Stack Overflow

@wcandillon You can also trick TypeScript by casting this into any which will prevent you from the TS2339: Property 'name' does not exist on type 'Function'. error.

Example:

    toString(): string {
        return (<any>this).constructor.name;
    }

The question is: why it's not part of TypeScript? Doesn't Function has .name in specification?

The question is: why it's not part of TypeScript? Doesn't Function has .name in specification?

The name property is only available in ES6/ES2015-compliant engines. Include es2015 in your --lib value to get the property declaration.

True. Thank you!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

DanielRosenwasser picture DanielRosenwasser  路  3Comments

Antony-Jones picture Antony-Jones  路  3Comments

remojansen picture remojansen  路  3Comments

blendsdk picture blendsdk  路  3Comments

weswigham picture weswigham  路  3Comments