-
Notifications
You must be signed in to change notification settings - Fork 9
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
Port JavaScript to TypeScript, Phase 1 #134
Conversation
also brandmark props should be optional bc they have default values
and add types for react-helmet
not done! see ts errors in setSpace.ts
not done; there are types to pass thru because <Tile> is polymorphic and can be rendered as <a> with its associated props/attributes
this is a proof of concept for components that ingest graphql data. graphql queries assume all fields are nullable by default. typescript would then demand we handle all null values, which sucks and will make code less readable unless we can guarantee the fields are never null in the graphql schema. see here https://www.gatsbyjs.com/docs/how-to/local-development/graphql-typegen/#non-nullable-types in the case of people, we can guarantee certain fields, e.g. "html" is always present, so is "frontmatter". fields like "bluesky" is definitely null-ish but i'm not sure if it's actually null or just, say, empty string
i am kind of muddling through this attempt at making <Tile> work as a polymorphic component because in some cases it renders out an <a> instead of a <div>. right now it doesn't really cover the condition where if `as="a"` is passed as a prop, then the html attributes of <a> are allowed
the problem here is that when <Action> is used, it can be a <Button> or a <Link> or it can be an obfuscated version of those (see `withObfucscation`). What it becomes is dependent on the combination of props and its values that passed to <Action>. i'm either not good enough at typescript to know what to do here or maybe we would have to revisit this approach????
Sorry for my delay in reviewing this -- the family (including me) got hit with all the casual diseases at once! |
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.
thank you so much for taking this on, it looks great! My logic for reviewing a major refactor like this is to just make sure it passes CI!
(which is just to say, I glanced at the actual lines and it looked good, but I didn't dig incredibly deep since even if I noticed something that I had an opinion about I wouldn't wanna raise it!)
YOLO MERGE FROM SPAIN |
Nobody expects the Spanish rash decision. |
See #133.
This is about a day's work and stops just short of addressing some particularly tricky problems (and maybe they are only tricky for me and not someone with better knowledge of TypeScript + Gatsby). Thankfully Gatsby's build process is very forgiving and doesn't actually do strict type-checking before a build. You should see the type problems in a lint, though. It would be reasonable to break up future TypeScript work in follow-up PRs if we don't want to address it all at once.
Additional guidance / reference is here: https://www.gatsbyjs.com/docs/how-to/custom-configuration/typescript/
What's done
tsconfig.json
to root. Its main purpose is to configure paths relative to./lib
for the TypeScript compiler so that imports do not have to be rewritten.gatsby-config.js
to automatically generate types for graphql queries to./lib/gatsby-types.d.ts
. There is likely more to be done here -- see below../lib/index.d.ts
to allow importing certain image assets../lib
(excluding templates) have been ported to TypeScript. Most modules have been extremely cooperative. Some general points about strategy:React.FC
.PageProps
(Gatsby) orReact.PropsWithChildren
(because usually the component needschildren
typed).prop-types
package to define typesdefaultProps
in favor of default valuessetSpace
et al accept string arguments in a specific format. Instead of typing only asstring
, which is unhelpful, I started an approach where only acceptable literal string values are valid. This way, illegal values can be type-checked@types/react-helmet
to provide userland type definitions for thereact-helmet
package; this can be removed if Helmet is ever replaced by Gatsby Head.Remaining issues (see also notes in relevant commits)
./lib/templates
need to be ported to TypeScript. I believe the main hurdle is the nullable graphql fields issue.<Tile>
is a polymorphic component that sometimes renders out an<a>
instead of aas="a"
is passed as a prop, then the html attributes of<a>
are allowed, and disallowed otherwise.<Action>
(and its sibling components) is tricky because when it is used, it can render a<Button>
, a<Link>
or it can be an obfuscated version of those (see
withObfucscation
). What it becomes is dependent on the combination of props and its values that passed to<Action>
. I'm either not good enough at typescript to know what to do here or maybe we would have to revisit this approach????setSpace
currently fails type-checking because the string literal types are probably not properly defined.Future work
prop-types
packageprop-types
ordefault-props