facebook / facebook/flow

Higher Order Classes

Open
#4,031 2 comments 0 reactions 0 assignees View on GitHub
Dominant language
Rust
Stars
22.3k
Forks
1.9k
PR merge metrics
No merged PRs in 30d

Description

Hi I'm writing a Library for interfacing with a REST api in a Domain friendly manner.

No I'm stumbled by the following case: I'm trying to express that I'm writing a function which
takes a class definition, and returns another class definition which is a subclass of the original
class definition, and that the subclass adds extra methods, but also contains all the fields of
the original class.

This is what I've got at the moment:

```js
// @flow

interface Resource {
id: ?number;

save(): number;

constructor(): void;

static one(id: number, queryParams: ?Object): number;
}

function makeResource(DomainEntity: Class): Class & T> {
return class extends DomainEntity implements Resource {
save(): number {
return 42;
}

static one(id: number, queryParams: ?Object = undefined): number {
return 42;
}
}
}

class Pokemon {
id: ?number;
}

Pokemon = makeResource(Pokemon);

Pokemon.one(1); // Works
Pokemon.two(1); // Error! (Because two is not a static method)

const bulbasaur = new Pokemon();
bulbasaur.save(); // Works
bulbasaur.update(); // Error! (Because update does not exist as a method)
```

It gives me an error saying:

```
This type is incompatible with the expected return type of
some incompatible instantiation of `T`.
```

[Here's a link to the code](https://flow.org/try/#0PTAEAEDMBsHsHcBQiCWA7ALgUwE6QIYDGWoASlgM6wCuOxAPACoB8oA3oqKCgCYBcoAPxpqAWwBGuANydQsivgBuWABQBKASInTkXQrDQUMOaoQywc6gYti8Z8jPgwpCoA6t6axknABpQAI7UuACeAAr4OPiiFAKCAPLiAFZYZhqgWj4yAL7IkNRoZigGoKL4ANZY5FS0DIwCbNz8Qpm4oNnMKgAisGXoAKKYKBghAgDC0PgUFEzM6RNTM9U0dFizoABkoCzssjhYGLRooIST06BYAB7YaDwUoD19aIPOI9yiAA7QWKJYmPfLWprHYcLhcBTKKwZbxtUFgrj7Q44Y4AFgATDJ4blZODHM5XO4VJ5odo-IFgjhwpForEhIkUmZQABeUAFHhYSDoLA8dKtHC7eEIg5HUDozFg3JcXLY06LUBhWCVUQlUHE4QwnA5ZAKpUlFllSqA1YqHU-Axqeym5VoAB0hIAjBbQCBQAB1CzlCiIK0GG0YeCwFSOqTOsA9SgZWAYUABnDlUBTC6XD6pbA8ZD6QzR8TUaDiKb4WjMjJYeDyxVmtDqGQ5vMF2g2iGqJ0u91xr21-MKBvUD48JzNkMu8P3NBRmMehP3K4pszcm1AA).

Here's the [code with a hack applied to force it to work](https://flow.org/try/#0PTAEAEDMBsHsHcBQiCWA7ALgUwE6QIYDGWoASlgM6wCuOxAPACoB8oA3oqKCgCYBcoAPxpqAWwBGuANydQsivgBuWABQBKASInTkXQrDQUMOaoQywc6gYti8Z8jPgwpCoA6t6axknABpQAI7UuACeAAr4OPiiFAKCAPLiAFZYZhqgWj4yAL7IkNRoZigGoKL4ANZY5FS0DIwCbNz8Qpm4oNnMKgAisGXoAKKYKBghAgDC0PgUFEzM6RNTM9U0dFizoABkoCzssoST06BjBoQ4WNjLtSRYAB7YaDwUoD19aIPOI9yiAA7QWKJYTBPS6rdYcLhcBTKKwZbxtcEQrhnDC0NCgAAsACYZIjcrJIY5nK53CpPLDtH5AsEcOFItFYkJEikzKAALygAo8LCQdBYHjpVo4XaIpHnVEY7H49qyPF6AxGUCEAT4NAhNlHE7IqqUFbEHGgFRKo4HJY6q7rLYsNT65Hiwg5ZD7RagMKwSqiErgsnCOE4B2IV3ukrssqVEHEFSB-4Ga3IKMetAAOhJAEZraAQKAAOoWcoUANu6NJjDwWAqNNSDNgHqUDKwDCgUs4cqgKagW7fVLYHiO+UN8TUaDiKb4WjqtBYeAuwsJ9QyAdDke0RNQ1TpzM55v5hfDhTL6jfHhONeVzM1p5oeuN3Otp4drt8xNAA). in which I just force the return type via casting, and it does seem to work.

Can someone point me in the right direction?

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.