Skip to content

Implementation of interface requires members redeclaration #5749

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
NekR opened this issue Nov 22, 2015 · 6 comments
Closed

Implementation of interface requires members redeclaration #5749

NekR opened this issue Nov 22, 2015 · 6 comments
Labels
Duplicate An existing issue was already created

Comments

@NekR
Copy link

NekR commented Nov 22, 2015

interface A {
    foo: Function;
}

class B implements A {
    constructor() {
        this.foo = () => {};
    }
}

Here TypeScript says that B incorrectly implements A and requires B to also have foo property with the same signature. So question is: why I need duplicate definition of properties when implement interface if I cannot override that definition anyway:

interface A {
    foo: Function;
}

class B implements A {
    foo: boolean;
    constructor() {
        this.foo = true;
    }
}

Here B again incorrectly implements A. Only way to fix it is to add foo:Function to B which absolutely has no point since A already has that.

@NekR NekR changed the title Implementation of interface requires props redeclaration Implementation of interface requires members redeclaration Nov 22, 2015
@GoToLoop
Copy link

Stating class B implements interface A is like promising to implement each member present in A inside B.
Remember that interfaces only describe members. They don't implement anything.
Implementation is reserved for classes. Classes can extend 1 other class and can promise to implement any number of interfaces.

@DanielRosenwasser
Copy link
Member

This looks like a duplicate of #340.

@RyanCavanaugh explained some of the rationale here: #340 (comment).

@DanielRosenwasser DanielRosenwasser added the Duplicate An existing issue was already created label Nov 23, 2015
@NekR
Copy link
Author

NekR commented Nov 23, 2015

@GoToLoop Thanks, I know what is interfaces and what is classes.

Stating class B implements interface A is like promising to implement each member present in A inside B.

Exactly. This is why duplicate declaration of members shouldn't be needed.

@DanielRosenwasser I am talking here about implementation of one interface, while @RyanCavanaugh shows examples of multiple classes. These cases are not relevant, you can handle multiple implementation in other way than since implementation. Still, I want to comment some moments:

it becomes very unclear/confusing what it means if you explicitly write those members:

In case of single implementation it's "incorrectly implements" if signatures are mismatched. This is why there is no rationale to duplicate them. Even more, with multiple implementations you still get that error:

interface A {
    foo:Function;
}

interface B {
    foo:boolean;
}

class C implements A, B {
    foo:boolean;
    constructor() {
        this.foo = true;
    }
}

Here "C incorrectly implements A", which is expected.

Even more, @RyanCavanaugh 's examples are relevant only to methods of class which absolutely should have their own rule since overloading is different topic.

One more interesting about multiple implementations and different methods signature is that there is only one way and all other ways report "incorrect implementation", this way:

interface A {
    foo(a:string):void
}

interface B {
    foo(a:number):void
}

class C implements A, B {
    foo: (a:string | number) => void;
    constructor() {
        this.foo = (a:string | number) => {}
    }
}

So again, if this is only way to handle multiple implementations and all other ways throw, then signature of foo() should be implicitly created. If you care about errors, it anyway will be reported on property assignment in constructor.

@NekR
Copy link
Author

NekR commented Nov 24, 2015

And please, open this back. I do not want create new issue for it
On Nov 23, 2015 6:40 AM, "Daniel Rosenwasser" [email protected]
wrote:

Closed #5749 #5749.


Reply to this email directly or view it on GitHub
#5749 (comment).

@kitsonk
Copy link
Contributor

kitsonk commented Nov 24, 2015

The issues is a duplicate of #340. While the example given demonstrates why it becomes complex when implementing multiple interfaces, it is the root cause of why the team of chosen to not implement this feature as #340 states, it is too complex and they consider it out of scope. Opening another issue will just get it closed and marked as a duplicate again.

Your example is that you have an interface that provides no implementation of method foo. It isn't just "redeclaring" as you asserted, it is about providing an implementation. The same goes for properties, because the class which implements an interface need to specify the implementation (e.g. a default value, or no default value or potentially property accessors).

The way you want to deal with the code seems more in line with the abstract keyword and classes, where you only have to implement the methods you have have marked as abstract in the final non-abstract class.

@jjrv
Copy link

jjrv commented Jan 18, 2016

This seems to work in a .d.ts and maybe covers some use cases:

export interface A {
    foobar: number;
}

export interface B extends A {
    new(): B;

    quux: number;

    // More members go here.
}

export var C: B;

C is now assumed to be a class correctly implementing interfaces A and B. Only the interface defining the actual type of C should have a new() method returning the interface itself. Then in a .ts file it's possible to do:

class D extends C {}

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Duplicate An existing issue was already created
Projects
None yet
Development

No branches or pull requests

5 participants