-
Notifications
You must be signed in to change notification settings - Fork 8.3k
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
[skip-ci] Core conventions #52397
[skip-ci] Core conventions #52397
Conversation
Pinging @elastic/kibana-platform (Team:Platform) |
> internal types. | ||
|
||
- 1.2 Classes must not be exposed directly. Instead, use a separate type, | ||
prefixed with an 'I', to describe the public contract of the class. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Discussed here #46668 (comment) and here #33396
src/core/CORE_CONVENTIONS.md
Outdated
}; | ||
|
||
// -- good (alternative) -- | ||
export interface IUiSettingsClient { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if there are cases where we prefer to have a dedicated interface instead of inferring a type from a class? If we don't have good examples of where this would be better, I can remove this from the conventions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pros having explicit interfaces:
There is a difference in that an interface is a source of truth when we define it explicitly. it means that we have control of what properties are a part of a public contract.
Better tooling, as there are no intermediate types. Whenever I click Go to definition
on SavedObjectsClientContract
it navigates to Pick
type.
Cons:
It creates an additional burden to define contracts manually.
Separates docs for an interface and implementation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Personally, I prefer explicit interfaces. I'd rather be deliberate about choosing to expose a property or method rather than allowing it to happen without notice (though the api-extractor tooling may make it more obvious).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not completely convinced by the benefit of a separate interface. Adding a public method to an interface doesn't make it more obvious that it will change the API contract than adding a public method to a class.
It seems like typescript support for private named fields will land in February https://github.com/microsoft/TypeScript/wiki/Roadmap#38-february-2020. If classes support real private fields/methods it will remove the need for an intermediate type (whether an explicit interface or PublicContractOf
). I see real private fields as the best solution, source code and docs live next to each other, no intermediate types, no type duplication. When Kibana adopts TS 3.8 would we still prefer a separate interface?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When Kibana adopts TS 3.8 would we still prefer a separate interface?
Don't think so. IIRC public/private field separation was the main reason for an explicit interface introduction.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it could be slightly easier to migrate from PublicContractOf
to private fields, but it wouldn't be that much work to migrate away from separate interfaces either.
Since we're hopefully adopting a new convention soon, it probably doesn't matter too much that we have two alternatives. I can flesh out the comment section to mention the pro's and cons of both conventions and mention that we're hoping to adopt private fields once it's available.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Works for me. Agreed that in most use-cases real private fields works well.
src/core/CORE_CONVENTIONS.md
Outdated
> churn when we know related API methods will be introduced. | ||
|
||
## 3. Tests and mocks | ||
- 3.1 Declary Jest mocks with a temporary variable to ensure types are |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
> hovering over the type in a code editor. | ||
|
||
## 2. API Structure and nesting | ||
- 2.1 Nest API methods into their own namespace only if we expect we will be |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Discussed here: #48431 (comment)
@elastic/kibana-platform Are there other conventions you can think of that's worth documenting as part of this PR? |
src/core/CORE_CONVENTIONS.md
Outdated
> Why? Without the temporary variable, Jest types the `start` function as | ||
> `jest<any, any>` and, as a result, doesn't typecheck the mock return | ||
> value. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TIL
src/core/CORE_CONVENTIONS.md
Outdated
}; | ||
|
||
// -- good (alternative) -- | ||
export interface IUiSettingsClient { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Personally, I prefer explicit interfaces. I'd rather be deliberate about choosing to expose a property or method rather than allowing it to happen without notice (though the api-extractor tooling may make it more obvious).
Typo Co-Authored-By: Josh Dover <me@joshdover.com>
* Table of contents for conventions * Add Core Conventions * Add Tests and mocks section * Update src/core/CORE_CONVENTIONS.md Typo Co-Authored-By: Josh Dover <me@joshdover.com> * Add pro's/con's for alternatives to private fields support Co-authored-by: Josh Dover <me@joshdover.com>
Summary
Adds conventions adopted by the Platform team for
src/core
.Checklist
Use
strikethroughsto remove checklist items you don't feel are applicable to this PR.For maintainers