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...
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!
Most helpful comment
It is easy to fix.
Just declare 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.