-
Notifications
You must be signed in to change notification settings - Fork 233
Split types.ts #68
Comments
I keep going back and forth on this one in my head. These are just type defs / interfaces to help with typing return values and parameters - likely would never need to use them separately. We could move to individual files and play with the TypeScript namespace/module merging and see. I would like to keep the ability to just include "types" whatever the syntax is - and not have to include lots of files if I needed to use more than one type. Splitting it does make sense as these grow, will be much easier to find and update stuff - but there is always ctrl+F. Someone can convince me either way probably, let's discuss on this weeks call and make a decision. |
Assign this to me and I'l create a PR that shows it in action and we can decide if good or bad idea after. |
All set, thanks for having a look. |
Points to be dealt with: |
Looked at the PR - I see all the types broken out, but not sure which of the above points it covers? I guess my 2c:
|
The [ ] were meant to indicate a "todo" for myself :) |
https://github.com/Microsoft/TypeScript/wiki/Coding-guidelines states
And in https://github.com/Microsoft/TypeScript/blob/master/src/compiler/types.ts we can see that they mix types/interfaces/enums in their types. A file/module with only an interface export generates an interfaceName.js file with So I started to look at how vscode does it and I kinda like their approach. They export interfaces alongside with the implementation of the thing that is used which looks clean to me. This leads to files like https://github.com/Microsoft/vscode/blob/5b9ec15ce526decc5dd0488339e798f6bcb4ec46/src/vs/editor/common/commonCodeEditor.ts with many import statements. I myself like the readability and clear intent of specifying what we import into a class vs using import *. Side note: I have no idea what's going on at the end of their https://github.com/Microsoft/vscode/blob/5b9ec15ce526decc5dd0488339e798f6bcb4ec46/src/vs/base/common/types.ts So heres my two cents that we can discuss -
Edit: Let me know if this is unclear or if anyone wants me to cook up some sample code to show how these style guidelines could be implemented on any current piece of code. Not doing that before we either accept this proposal or someone asks me to ;) |
Re cherry picking perhaps this is what @mike-morrison is talking about in #85. I think we should solve that issue before deciding on the Locale enum as they are interconnected. |
@pbjorklund Wow! That vscode is beautiful. It's so consistent in style. Speaking of, can we relax the tslint rules a bit. Seeing the squgglies and having to delete white space to make them go away is getting on my nerves for something that is going to get transpiled and minified anyways. CRLF at the end of files, etc. Is there some other gain I am missing? |
@patrick-rodgers any thoughts on the above before I start? |
I don't see any value in duplicating all the classes as interfaces, and I don't see that supported by the files you linked. They are exporting both interfaces and classes as are we - but not 1 interface per class. Also, I've been a fan of keeping all the common utility types in a single types file from the beginning. They are also using both import syntaxes as appropriate; * and {} as are we. Classes in TS are essentially also interfaces. If I have a class and a function like:
I can already do the below because the type checking is structural.
Implementing a rule that for every class we write we also have and maintain a duplicate interface doesn't add any value or make consumption easier, it just increases overhead. Not sure this is worth pursuing. |
I like to program against interfaces instead of implementations, perhaps my background from other languages are taking over to much compared to what the TS best practices/environment are. When you use a class as an interface in TS you also get the internals of the class.
I want us to agree on something and put it in a styleguide for when other people come along and start thinking about the same thing I did. Is it the implied "always" you don't like? Then how about something like:
1.1 If the interface is shared between multiple files, export the interface in /src/types/types.ts When it comes to functions that have complicated signatures I like to have an interface for them, just makes life easier, but don't have special other reasons besides that. If no-one cares about discussing things like these I shouldn't waste my energy and go hack on some other part of the library. Just let me know. |
I think we are using interfaces where it makes sense, for provisioning providers for example. Maybe there are places where we could make things more generic, on the whole I think we are in pretty good shape. Take web for example - will we realistically have separate web implementations such that we need an IWeb (I know you are opposed to using the "I" prefix)? While I agree with your point 1, it is just good programming practice to use interfaces when appropriate - so do we need to call that out for folks? As for the location, we could put them all in types.ts - currently we are keeping the generic ones we don't own (i.e. those that come from the service declarations) in types and the ones we own near where they are used (again I'll use the example of configuration providers). That seems easier to me to edit, find things since we will likely change our interfaces, but never (until there is a service update) the ones we don't own, so stuffing them in a giant long file is less of a pain. I am not sure what you mean regarding interfaces for functions - so you mean the parameters? So instead of function f(x,y,z,f,e,s,a,r,fg,d,ad) it would be f(foo: IFoo)? |
It's very useful to be able to easily switch out the implementation when doing unit tests or functional tests where you want to isolate what effect a dependency has on a function (testing glue for instance).
After doing research it seems that there is no consensus at all in the TS community... Let's just pick a standard and go with it, that's more important then discussing forever how to name them and never actually getting to implement the names. And when I saw that the SharePoint Framework uses INaming I think we should probably go with that as well. If you are ok with that I'l go ahead and add it to the style guide.
Not sure if that's a question or a statement?
How about this for a section in the style guide?: InterfacesWhen writing a generic interface that is used at multiple locations or the interface is external it should be put into That seems very close to the latest proposition I had, or am I missing something?
One usage for that is typing configuration objects, but I don't have a real preference on lots of params vs config objects as long as they have no behavior. Also not sure if typing functions actually give anyone but me any extra value, I just like to be able to read "function contracts" separately, but due to the ... promiskuity? of JS I don't know a way to make them useful in an editor or at compiletime. Let's not include that one at all for now. So if we can agree on that I can go hunting across the codebase and see if we already follow this or not. If we already do it this way it's great because then we would already be in line with what we write in the style guide. |
Going to close this one for now, please reopen it if you have an update or any progress to add. Been open for a bit with no activity. |
Should we split the interfaces in types.ts to own files?
Usage of type is now
import * as Types from "./types";
will have to becomeimport { Type } from "./types/type.ts";
The text was updated successfully, but these errors were encountered: