-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Closed
Description
Sorry if this was a dump question- In this connected component, I'm confused about the Types
and Types.RootState
. Is the Types
a npm package cuz it doesn't seem to be in the package.json
?
carpben and liuliangsir
Activity
piotrwitek commentedon Jul 25, 2018
This is a global scope type annotation, if you'd open project and search all references everything should be clear
carpben commentedon Feb 3, 2019
Thanks for this guide.
I find
import Types from "Types"
very confusing. According to the syntax Types refers to a library named Types, but after checking in NPM it's not the case. Shouldn't it beimport Types from "./Types"
.There is still the challenge of how and where to create the "RootState" type. There should be a State type defined in each of the separate reducers. I guess file containing the combine reducers is the appropriate place for the RootState type. Makes sense?
piotrwitek commentedon Feb 3, 2019
@carpben I'm using Ambient Modules technique, you can learn more here:
https://www.typescriptlang.org/docs/handbook/modules.html#ambient-modules
And also here: #97
chawax commentedon Feb 3, 2019
I use
typesafe-actions
library to achieve this. It makes it easy to create aRootState
type that you can export from the same file where you combine reducers.For example :
Then it
mapStateToProps
for example :piotrwitek commentedon Feb 3, 2019
@chawax I used that in the past but it's not an optimal solution and introduces all kind of issues when scaling your codebase, primarily because then in your components you are adding hard-dependency on this module like this:
It will add all of your reducers and their dependencies as a dependency to your components and you'll have to mock tons of unrelated stuff when trying to test in isolation. That means you have tight coupling in your codebase and this is considered a code smell.
With my approach (the one that is using purely ambient type definition to define global scope types using
d.ts
files #97), you're not be impacted by any of that issues.piotrwitek commentedon Feb 3, 2019
@chawax I just realized there is more to my argument above that needs to be added here:
Also your
@Types
imports are consistent in every module across the entire application without a worry where does it come (you can always jump to it with F12). And all of the above reasons will make your application easier to extend and to maintain in the long run.chawax commentedon Feb 3, 2019
Something like that ?
types/index.d.ts
file :with
AuthState
defined in myAuthRedux
fileThen :
piotrwitek commentedon Feb 3, 2019
Yes correct, but notice I prefer to add "Ambient Modules" technique (linked above) because that gives me absolute import capability, without paths mapping and aliasing configuration concerns.
I don't really like relative imports for global stuff because it's hard to maintain.
chawax commentedon Feb 3, 2019
I don'k now ambient modules (a lot of things to learn about TS yet !). Do you have any example how you declare such modules to have absolute imports ?
piotrwitek commentedon Feb 3, 2019
Please check
/playground
project here in the repository, you can find it in thestore
folderchawax commentedon Feb 3, 2019
Great ! Thanks a lot !
carpben commentedon Feb 3, 2019
@piotrwitek ,
When RootState is imported would you consider it to be a hard import?
piotrwitek commentedon Feb 3, 2019
Ad1) By hard dependency I mean that you have a runtime dependency that you have to mock it during testing in isolation. I agree the example I have provided is not the best one, but you can imagine real-world situation (commonly happens with the ducks-pattern), when you're importing the type (State, ActionType) and some other runtime export (selectors, actionCreators) from the same file, then it'll be a problem.
But with the clear separation of type imports (
*.d.ts
files) and runtime imports from regular modules the intention is more clear and it's easier to find the problem in such case.Ad2) I don't understand your question. An ambient definition doesn't import anything, you simply extend its definition across multiple files, that's how it works.
carpben commentedon Feb 14, 2019
Though it just imports a type, it will make rootReducer a dependency of the component file, which will create a problem when trying to test the component independently?
4 remaining items