Skip to content
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

ESLintify the library and its examples, enable linting in CI #112

Merged
merged 5 commits into from
Feb 28, 2024

Conversation

matux
Copy link
Collaborator

@matux matux commented Feb 24, 2024

Most changes come from the updated package-lock.json in the nextjs example project.

Description of the change

This is the ESLint portion of the prettier/eslint + ci effort. All warnings and errors have been addressed.

Explanatory comments in file changes.

Type of change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Maintenance
  • New release

Checklists

Development

  • Lint rules pass locally
  • The code changed/added as part of this pull request has been covered with tests
  • All tests related to the changed code pass in development

Code review

  • This pull request has a descriptive title and information useful to a reviewer. There may be a screenshot or screencast attached
  • "Ready for review" label attached to the PR and reviewers assigned
  • Issue from task tracker has a link to this pull request
  • Changes have been reviewed by at least one other engineer

@matux matux self-assigned this Feb 24, 2024
@matux matux changed the base branch from main to matux/format February 24, 2024 19:22
@@ -1,3 +1,5 @@
/* eslint-disable no-unused-vars, react/jsx-no-undef, react/prop-types*/
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file isn't part of a project but a repertoire of snippets exploring how Rollbar may be used.

So, these checks are bothersome, and the snippets are more explanatory if they look "as if" they were part of an actual larger project.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I may end up adding this as a file comment, actually.

index.d.ts Outdated
@@ -26,7 +26,7 @@ export interface ErrorBoundaryProps {
errorMessage?: string | (() => string)
extra?: Extra | ((error: Error, errorInfo: ErrorInfo) => Extra)
level?: LEVEL | (() => LEVEL)
callback?: Callback<any>
callback?: Callback
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When omitting the type parameter, it defaults to any already.

render(ui, {
wrapper: (props: { children?: ReactNode }) => (
<Provider {...{ children: props.children ?? <></> }} {...providerProps} />
),
Copy link
Collaborator Author

@matux matux Feb 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one was a fun type-structure puzzle.

So, Provider expects a ProviderProps-type-like structure which is defined like so:

export interface ProviderProps {
  Rollbar?: new (options: Configuration) => Rollbar
  children: ReactNode
  config?: Configuration | (() => Configuration)
  instance?: Rollbar
}

The solution is two-fold.

First

We need to acknowledge that we're providing the expected type structure through two arguments, props supplies the only required prop children, and providerProps supplies the rest of the props which are all optional.

Second

This is one is a bit harder to explain. The function render is loosely declared as: render(_, RenderOptions), we only care about the second argument RenderOptions which has a bunch of props and a wrapper?: React.ComponentType which is in turn, the one we care about.

ComponentType is defined as:

type ComponentType<P = {}> = ComponentClass<P> | FunctionComponent<P>;

Since we're passing a function (props) => ..., we are matching FunctionComponent's structure which has a bunch of props and the main one, the function, which is defined as:

interface FunctionComponent<P = {}> {
  (props: PropsWithChildren<P>, context?: any): ReactElement<any, any> | null;
  ...
}  

So, the props we get here: (props) => <Provider {...props} {...providerProps} />, is of type PropsWithChildren which is defined:

type PropsWithChildren<P> = P & { children?: ReactNode | undefined };

And therein lies the second problem. The children prop is optional, but ProviderProps requires it. So, we solve this by creating a new object that matches the structure in ProviderProps, and we either pass props.children if there's something in it, or an empty node.

And voila, all types check!

Fun for the whole family.

A note on P: Given there's no type parameter defined in wrapper?: React.ComponentType, we know for a fact that that P = {}, therefore props is effectively of type { children?: ReactNode }.

@matux matux marked this pull request as ready for review February 27, 2024 16:31
mudetroit
mudetroit previously approved these changes Feb 27, 2024
.github/workflows/ci.yaml Show resolved Hide resolved
examples/nextjs/pages/index.tsx Show resolved Hide resolved
@matux matux merged commit f8ca10e into main Feb 28, 2024
6 checks passed
@matux matux deleted the matux/eslint branch February 28, 2024 20:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants