1

I have the following definition in Typescript

**sample.d.ts**

declare namespace Sample {

    class Widget {
        name(): string;  // gets the name
        name(name: string): void;    // sets the name
    } 
}

When I create the following derived Type, I get no warnings:

export class BarWidget extends Sample.Widget {

    public name(): string {
        return '';
    }
}

However, when I create the following Type, I get a Typescript error:

export class FooWidget extends Sample.Widget {

    public name(name: string): void {

    }
}

The error message is:

Class 'FooWidget' incorrectly extends base class 'Widget'. Types of property 'name' are incompatable. Type '(name: string ) => void' is not assignable to type '{ (): string; (name: string): void;}'

Update:

This question relates to support for libraries such as kendo.ui:

https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/kendo-ui/kendo-ui.d.ts#L3373

In that code file, the value property of the DropDownList needs to be set and get'ted using the following syntax:

let foo = dd.value();
dd.value('new value');

My final solution was to change the definition in kendo.ui.d.ts to:

declare namespace Sample {
    class Widget {
        name(name?: string):string
    } 
}
Darren Neimke
  • 218
  • 4
  • 18

1 Answers1

2

TypeScript cannot do all of the same overloading as other typed languages (e.g. Java). See this question.

In order to overload this you have to use TypeScript's bizarre multi-function definition which is described in more detail in the question I linked to.

declare namespace Sample {

    class Widget {
        name():string;
        name(name:string):void;
    }

}

export class BarWidget extends Sample.Widget {

    private _name:string;

    name():string;
    name(name:string):void;
    name(name?:string):string {
        if(name) {
            this._name = name;
        } else {
            return undefined;
        }
    }

}
Community
  • 1
  • 1
Pace
  • 41,875
  • 13
  • 113
  • 156
  • That works outside of the ambient namespace. Using the amended sample gives an error message: 'an accessor cannot be declared in an ambient context' – Darren Neimke Jul 23 '16 at 01:21
  • Thanks again for the help. This would work but it doesn't technically meet the requirement as it changes the underlying definition of name from a method to a property. I've added an Issue on the Typescript repo for this: https://github.com/Microsoft/TypeScript/issues/9907 – Darren Neimke Jul 23 '16 at 01:48
  • refer to my final comments here for additional context: https://github.com/Microsoft/TypeScript/issues/9907 – Darren Neimke Jul 23 '16 at 02:14
  • Ok, I did a bit more research and came up with a solution that should work for you. – Pace Jul 23 '16 at 10:52
  • Thanks for the help... I ended up going with: ` class Widget { name(name?: any): any; } ` – Darren Neimke Jul 23 '16 at 19:37
  • At least change those `any` to `string`? – Pace Jul 23 '16 at 23:56
  • I had the any return to cover void. I could probably do: `name(name?: string):string|void;` – Darren Neimke Jul 24 '16 at 03:31
  • 1
    A void function returns undefined. You can return undefined from a function with return type of string in the same way you could return null. – Pace Jul 24 '16 at 03:37
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/118119/discussion-between-digory-and-pace). – Darren Neimke Jul 24 '16 at 03:41