-
Notifications
You must be signed in to change notification settings - Fork 1.9k
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
Add documentation for interface declarations #833
Comments
Update: I have found a solution to this problem, by declaring a I would be greatful if someone would confirm that this is the expected behaviour and that it was a user error on my part before closing this issue. Thanks. |
I see that another solution to this is to use an I could not find any documentation for this though. Is the reason for this being undocumented that it is only supported because of TypeScript compatability? |
Glad you found the solution — declaring a class also creates a runtime identifier, so that's definitely not what you wanted. I'm going to re-title this issue and leave it open as a prompt to add documentation for interfaces. |
Thanks for your answer @samwgoldman I did try to have the BTW, just as a side note, it would be very nice to be able to do this: interface ITest {
test(val : number) : string;
}
class Test implements ITest {
test(val : number) : string {
return val.toString();
}
} And have flow varify that Test actually implements ITest. I guess |
Pending the documentation, can someone explain the use of For example: |
Given |
indeed they mostly are; there's at least one exception ( |
What is "implements" alternative for classes? type IUser = {
id: string;
relations: Array<IUser>;
}
class CustomUser implements IUser {
id: string;
relations: Array<CustomUser>;
displayName: string;
}
function doSomethingWithCustomUser(user: CustomUser): void {
// code
}
function doSomethingWithBaseUser(user: IUser): void {
// do not knows about user.displayName
} |
@zerkalica Thanks for providing that example! At the moment Flow doesn't support an However, there is a subtle type error in your example code, which I'll try to explain.
Flow is complaining that the Hopefully Here's the TL;DR, though. We don't currently support an Hope this helps! |
@samwgoldman Thank you for the answer. |
What's the status on documentation for this? Is there a way to submit update to the documentation site or a WIP? |
flowtype.org is powered by GitHub pages, so to contribute you just need to send a PR to the gh-pages branch of this repo. |
@samwgoldman I'd like to document this, but actually I don't understand at all, what is the point of interfaces in flow. Seems that they use is completely covered by types: |
Don't know of what differences there are between an |
@vaukalak I see you commented in a related issue, som obviously you were already aware of what I stated above. Sorry for the noise. |
Summary:Related to #833, adds note about mixins for declared classes and adds a note about similarity to TypeScript and Dart. Closes #1337 Reviewed By: samwgoldman Differential Revision: D3114147 Pulled By: gabelevi fb-gh-sync-id: 4ac560e03864686005da0aaaf3dc1b0b694b2fb8 fbshipit-source-id: 4ac560e03864686005da0aaaf3dc1b0b694b2fb8
@samwgoldman, you said support for class Foo extends Bar implements Baz, Qux {} |
Jed, that syntax might too intrusive into ES6.
How about:
`Foo: $Implements<Baz, Qux>`
?
Also, I think you can already do this:
`(new Foo(): Baz)`
…On Tue, Jan 17, 2017, 11:12 Jed Mao ***@***.***> wrote:
@samwgoldman <https://github.com/samwgoldman>, you said support for
implements is a TODO for you. Is there an issue number to track this? I'm
very interested in the following syntax:
class Foo extends Bar implements Baz, Qux {}
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#833 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/ACmsInIgbou_d-isiWmJq098RIdRM34bks5rTJQGgaJpZM4GArgY>
.
|
@mhagmajer |
I should have noted that i stole the syntax from TypeScript. |
What about: |
@mhagmajer the problem with the /* @flow */
class Foo {
qux = 'corge';
bar() {
return 'baz';
}
}
interface Baz {
qux: string;
}
const x = (new Foo(): Baz);
x.qux; // OK
x.bar(); // Error: property 'bar' not found. Flow and TypeScript both are interested in aligning with ES6 as much as possible, so I'm not sure how "intrusive" the @dimpiax, I don't think a simple To translate the "broken" Flow example above into TypeScript, you can see how it preserves both the class and the interface type information upon instantiation. interface Baz {
qux: string;
}
interface Thud {
fred: number;
}
class Foo implements Baz, Thud {
qux = 'corge';
bar() {
return 'baz';
}
}
const x = new Foo();
x.bar(); // OK
x.qux; // OK
x.fred; // OK |
Jed,
The expressions I mentioned would only serve as "type gurads" for Flow,
e.g.:
```
(new Foo(): Bar); // just for Flow
```
If you wanted an instance of `Foo` you would do the ordinary:
```
const x = new Foo();
```
The other expression (`$Implements`) wouldn't cause constructor to run
which might have some side effects, however, it's not available in Flow.
…On Fri, Jan 20, 2017, 20:15 Jed Mao ***@***.***> wrote:
@mhagmajer <https://github.com/mhagmajer> the problem with the (new
Foo(): Baz) syntax is not only that you have to type that every time
you're interested in using Baz props, but then you also lose type
information about Foo. Consider the following example
<https://flowtype.org/try/#0PQKgBAAgZgNg9gdzCYAoVBjGBDAzrsAMTjjAG9UwwBHAVwA8wBeMAcgzgCcBzAU1YDclMACNsnABQBKcsKqdeAF1qcAdmzEAvQcIC+qfagCWqxb05RsGXmABC2TbKp16ALjC5FnE9yGGOqp5gjCwSqrxIxHDS7vaaUkL0AHQuiUlikglgwMBgAKKcnFzuAA5FJeaKAJ4a4qxgqnCKYFBwtKoAJkmoQA>
:
/* @flow */
class Foo {
qux = 'corge';
bar() { return 'baz';
}
}
interface Baz {
qux: string;
}
const x = (new Foo(): Baz);x.qux; // OKx.bar(); // Error: property 'bar' not found.
Flow and TypeScript both are interest in aligning with ES6 as much as
possible, so I'm not sure how "intrusive" the implements syntax would be.
@dimpiax <https://github.com/dimpiax>, I don't think a simple class A: B,
C, D would work either, because you can only extend one class, but you
can implement one or more interfaces. It's a bit misleading that you can
just list them out like that w/o some kind of separation between the class
you're extending and the interface(s) you're implementing.
To translate the "broken" Flow example above into TypeScript
<http://www.typescriptlang.org/play/index.html#src=interface%20Baz%20%7B%0D%0A%20%20qux%3A%20string%3B%0D%0A%7D%0D%0A%0D%0Ainterface%20Thud%20%7B%0D%0A%20%20fred%3A%20number%3B%0D%0A%7D%0D%0A%0D%0Aclass%20Foo%20implements%20Baz%2C%20Thud%20%7B%0D%0A%20%20qux%20%3D%20'corge'%3B%0D%0A%20%20bar()%20%7B%0D%0A%20%20%20%20return%20'baz'%3B%0D%0A%20%20%7D%0D%0A%7D%0D%0A%0D%0Aconst%20x%20%3D%20new%20Foo()%3B%0D%0Ax.bar()%3B%20%2F%2F%20OK%0D%0Ax.qux%3B%20%2F%2F%20OK%0D%0Ax.thud%3B%20%2F%2F%20OK>,
you can see how it preserves both the class and the interface type
information upon instantiation.
interface Baz {
qux: string;
}
interface Thud {
fred: number;
}
class Foo implements Baz, Thud {
qux = 'corge';
bar() {
return 'baz';
}
}
const x = new Foo();x.bar(); // OKx.qux; // OKx.fred; // OK
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#833 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/ACmsItcrkk-pqIw_1RhnpI8WR9OJDTn7ks5rUQfngaJpZM4GArgY>
.
|
One way to do this: interface Baz {
qux: string;
}
interface Thud {
fred: number;
}
class Foo /* implements Baz, Thud */ {
qux = 'corge';
fred = 0;
}
/*:: ((({}: any): Foo): Baz); // Foo implements Baz */
/*:: ((({}: any): Foo): Thud); // Foo implements Thud */ This guarantees that |
implements has existed for a while |
I am using
declarations
to abstract away third party code, but also to losen the coupling to a specific implementation. However, I am experiencing a problem, which is that I am unable to make aclass
compatible with adeclaration
.I have created a minimal repo where you can see the issue. If you look at
src/index.js
, there is afunction
and aclass
that are equal to each other, and both are (should be) compatible with thedeclaration
found inlib/i-test.js
.Running flow on this code gives error
This type is incompatible with
for the class, but not for the function. I might be misstaken in the usage, but if so I can't see the incompatability.PS. I am using flow-bin v0.16, to install dependencies run
npm i
The text was updated successfully, but these errors were encountered: