-
Notifications
You must be signed in to change notification settings - Fork 242
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
When reviewing some code in this repo, I noticed some potential bugs (or at least non-ideal error-handling cases) that arose from TypeScript's default behavior of assuming that all index operations yield valid values. That is, by default TS assumes that if `x: Record<string, Y>` then `x[anyString]` is `Y` rather than `Y | undefined`, and it assumes that all array access attempts are in bounds. noUncheckedIndexedAccess changes this so that you generally need to actually make sure that your indexes worked. (This is a bit awkward for arrays because it doesn't let you rely on `.length` checks, but it's not the end of the world.) More details on the flag are available at microsoft/TypeScript#39560 Here's an overview of the sorts of changes involved: - One of the issues tracked in #624 is that buildComposedSchema could fail with unclear errors if the input schema doesn't declare directives correctly; the code assumed that any `@join__owner` or `@join__type` directive application *must* have a non-null `graph` argument whose value matches one of the `join__Graph` enums. We probably should validate the definitions, but in the meantime this PR validates that the value we get out of the directive application is good, with explicit errors if not. - Our code uses a lot of record types like `{[x: string]: Y}`. noUncheckedIndexedAccess means we need to actually check that the value exists. (Another alternative would be to change to `Map` which does not have this issue.) I added a helper `getOrSetRecord` which allowed us to express a very common case more succinctly, which also led to less duplication of code. - In some cases where it is very clear from context that a lookup must succeed (eg, a length check), I just used `!`. - Some cases in composition explicitly checked to see if directives had arguments but not if it had at least one argument; adding a `?.[0]` helped here. - Many cases were fixed by just using `?.` syntax or saving a lookup in a variable before moving on. - Iteration over `Object.keys` could be replaced by `Object.values` or `Object.entries` to eliminate the index operation. - In some cases we could change the declaration of array types to be "non-empty array" declarations, which look like `[A, ...A[]]`. For example, the groupBy operation always makes the values of the returned map be non-empty arrays. I was also able to replace a bunch of the FieldSet types in the query planner with a NonemptyFieldSet type; there are other places where it might be good to improve our checks for nonempty FieldSets though. - Nested `function`s that close over values in their surrounding scope can't rely on narrowing of those values, but arrow functions assigned to a `const` that happen after the narrowing can, so in some cases I replaced nested functions with arrow functions (which generally involved moving it around too).
- Loading branch information
Showing
25 changed files
with
353 additions
and
292 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.