-
Notifications
You must be signed in to change notification settings - Fork 394
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
Implicitly Existential: Add noImplicitAny to TypeScript config, fix related issues #330
Conversation
This will help us avoid errors about untyped packages once noImplicitAny is enabled. Also bump our webpack version to align types to most of the webpack versions referenced in the type packages.
These were from a previous iteration of db code, and are not currently in use.
This is more reflective of what we're working with, and will ensure we don't start accessing properties willy nilly.
We still need to improve validation to ensure the API gives us data that fits the specified types, but this gets us to avoiding anys.
This matches existing uses in the code that were coming in as anys and avoiding type checking.
This takes care of good-enough typing for the nested function parameters.
This is used in the UI slice as well as the activity detail/listing components.
These were dangling, leading to missing types all the way down the selector tree.
noImplicitAny will frown upon our existing approach, so introduce a new one that preserves types all the way down.
81df7e0
to
b0f5ba1
Compare
The new approach validates the response at the highest level and then translates those types down into the remaining data handling.
Likely enabling strict mode will stop these from being resolved as any implicitly, but in the meantime type them explicitly.
These now explicitly check for the decimals fields that we expect exist.
Due to the fact that most webpack plugin type packages depend on specific webpack versions, and the way plugin signatures are resolved from minor version to minor version breaks, some forced casting is included to get to a compiling file while avoiding implicit anys.
The typing is generic rather than tied to ActivityItem, and allows us to ensure all the pieces are properly typed and the map correctly mentions properties that are valid for the object being adapted for UI display.
We ended up with some implicit anys and unexpected unknowns due to the JDT schema's inability to type a few properties. With noImplicitAny, this triggers actual errors, and we adjust for those here.
The day is here! Implicit anys are no longer allowed, and TypeScript will error on them. Explicit anys should also be avoided, but for now that's still treated as a warning.
The ethers logger was in use, making for confusing output.
When an Ethereum token price has more decimals than the fiatDecimals, BigInt would receive a floating-point number and error out; this commit adds a call to Math.trunc to truncate further precision (not round!).
b0f5ba1
to
91561bd
Compare
I've requested review from everyone who has touched code related to this. Here are some
Please everyone feel free to look at much more than the specific commits listed here 🙏 |
detailTransformer: (value: T[P]) => string | ||
} | ||
} | ||
|
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.
just a quick note that I really like this code and typing 💯
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.
So fancy
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 don't like single letter variables 😢
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.
A couple questions, but all for merging. Thanks for taking out the trash here!
@@ -85,7 +88,7 @@ | |||
"terser-webpack-plugin": "^5.1.1", | |||
"ts-loader": "^9.2.3", | |||
"typescript": "^4.3.2", | |||
"webpack": "^5.39.0", | |||
"webpack": "^5.58.1", |
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.
Ser. Seems like a Webpack bump should make it into the commit message 😄
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.
This bump is to the version that resolves anyway (due to the ^
), I just tried to be more explicit to see if I could deal with webpack @types tomfoolery (it didn't work).
@@ -19,7 +19,7 @@ export default function CorePage(props: Props): ReactElement { | |||
const [isNotificationsOpen, setIsNotificationsOpen] = useState(false) | |||
const [isDevToolsOpen, setIsDevToolsOpen] = useState(false) | |||
|
|||
function handleOpenHiddenDevMenu(e) { | |||
function handleOpenHiddenDevMenu(e: React.MouseEvent) { |
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.
Man I struggle with React types
@@ -28,11 +28,11 @@ test("round-trips mixed values with bigints correctly", () => { | |||
float: 132.167, | |||
exp: 12.683e13, | |||
string: "hello", | |||
nullCheck: null, | |||
nullCheck: null as null, // FIXME Fix when strict is enabled. |
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 don't get this one?
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.
Without strictNullChecks
, null
results in an implicit any
, because null
cannot be inferred as a type. strictNullChecks
makes null
and undefined
full types in the type system, so the explicit cast to the type is no longer required.
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.
(Great reminder, I forgot to hit these in the strict mode branch lol.)
@@ -403,12 +403,13 @@ export const selectAccountAndTimestampedActivities = createSelector( | |||
asset.symbol === assetItem.asset.symbol && asset.recentPrices.USD | |||
) | |||
|
|||
if (rawAsset) { | |||
// Does this break if the token is less than 1 USD? Hah... |
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.
Isn't this still an open question? Seems like we still want some sort of a TODO
here
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.
Bah. Yeah, I originally changed this to always assume the same side had USD on it, but then found that even though the docs promise it, the reality does not seem to match that promise. No surprise there, tbh <_<
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.
Actually we have access to each side of the pair's symbol here… Feels both type-able correctly and more easily detectable here. Added a TODO in the strict mode branch.
detailTransformer: (value: T[P]) => string | ||
} | ||
} | ||
|
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.
So fancy
@@ -194,7 +195,8 @@ export async function getTokenBalances( | |||
if (!isValidAlchemyTokenBalanceResponse(json)) { | |||
logger.warn( | |||
"Alchemy token balance response didn't validate, did the API change?", | |||
json | |||
json, | |||
isValidAlchemyTokenBalanceResponse.errors |
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.
👍
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.
Go go go 🚀
This PR enables the
noImplicitAny
rule in our TypeScript config:This required adding typing to a few places, and tightening up types in a few others. It
revealed a few issues with the type structures we were expecting in the WalletActivity*
components, partly related to capitalization and partly to type support for placeholders
we weren't using anymore.
In a few very specific cases types are forced using
as
. In general these are related tovery specific issues that can be fixed in the future, and are marked with
FIXME
.Draft until I double-check that functionality remains solid.