Repository: TypeScript
Issue: Methods are not accepted as implementation of abstract members with function type
Labels: Suggestion,Help Wanted,Experience Enhancement

# Bug Report

I am declaring a named type with the signature for an abstract method(ish)* on a base class. But I am not able to use the Signature type directly to declare the method, instead I need to pluck off `Parameters<Sig>` and `ReturnType<Sig>` to declare a "real" method. Given how methods usually behave in TS interfaces, this is certainly surprising.

* To expand on the motivation for doing this: The real-world use case involves a "pluggable" method where some subclasses have a `call` method that implements the interface, and others do `constructor(public readonly call: Sig, ...otherArgs)` so that they have an injectable `call` member. In either case, the consumer of the api just does `myObj.call(blah, blah, blah)` and it Does The Right Thing. I am declaring the named `Sig` to avoid repeating it everywhere.

### 🔎 Search Terms

abstract method member function TS2425

### 🕗 Version & Regression Information

> When did you start seeing this bug occur?

Repros in oldest and nightly in playground.


> This is the behavior in every version I tried, and I reviewed the FAQ for entries about _________
>
> "Bugs" that have existed in TS for a long time are very likely to be FAQs; refer to  https://github.com/Microsoft/TypeScript/wiki/FAQ#common-bugs-that-arent-bugs


I'll admit this is certainly _similar_ to the third from the last issue in that list: 
<blockquote>
<ul>
<li>A method and a function property of the same type behave differently.
<ul>
<li>Methods are always bivariant in their argument, while function properties are contravariant in their argument under <code>strictFunctionTypes</code>. More discussion <a href="https://github.com/microsoft/TypeScript/pull/18654">here</a>.</li>
</ul>
</blockquote>

However, that summary and the linked issue are all about bivariance/invariance/contravariance which controls matching semantics for functions with _different_ signatures. In this case, the signatures are identical, so that difference doesn't apply. This appears to be a different difference (at least to me). If this is intentional, perhaps the FAQ should be updated to focus less on variance. Ideally, explaining why even identical signatures are rejected.

Issue #27965 also seems related, but that case is a bit different. It was declaring an *actual* member, which may exist in JS land on the base, while this issue is specifically about adding an `abstract` member, which I would expect to be more like adding something to the `interface` portion of a class type, since it explicitly *isn't* set by the base in JS. Also that case tried to use `any` as the "function" type of the member, and I am using an exact-matching function type.

### ⏯ Playground Link

[Playground link with relevant code](https://www.typescriptlang.org/play?ts=4.8.4#code/C4TwDgpgBAyglgcygXigCgHYC4oYK4C2ARhAE4CUKAfLoSaQFAMCGRAzsKcwMbBTcAbZmzZQAQsOgBvBlDlRWHLrygEIxMjngIA3LPmLOPPmuAALAPYATNADp7zUgjY4ACo+amybADzaq5DgAShDAeKQYACrgEH6IVAwAvkyCwqIAImRwAG4QVgCyoZZWohAAHsAQGCXiklAy8qrq9Jg4+BoU9VCkoeEYuDpQiVAA9CNQgJxk+nKmxa20HZRS3b0RA0NJKUIiUJmkOXmFHaUVVTUSbNLTTR0AhFqIeo2z1vewj6PjAHIWlTjmcFEAHcLKQANaiOD9czQCxgMAWNhwSpQKxwHq8OAWDC3JJAA)

### 💻 Code

<!-- Please post the relevant code sample here as well-->
```ts
type Sig = (n: number) => number

abstract class Base {
    abstract member: Sig;
    abstract method(...args: Parameters<Sig>): ReturnType<Sig> // This works, but is something only a type theorist would love.
}

class DerivedMethods extends Base {
    member(n: number) { return n; } // <---- Error here ☹
    method(n: number) { return n; }
}

class DerivedMembers extends Base {
    member!: Sig;
    method!: Sig; // Note: this works in the opposite direction!
}
```

### 🙁 Actual behavior

> Class 'Base' defines instance member property 'member', but extended class 'DerivedMethods' defines it as instance member function.

### 🙂 Expected behavior

Compile without error