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

meta: validate defaultOptions for stricter option types #4901

Merged
merged 3 commits into from
Feb 1, 2024

Conversation

aduh95
Copy link
Contributor

@aduh95 aduh95 commented Jan 31, 2024

  1. Removes [key: string]: unknown from PluginOptions – that was probably added by mistake
  2. Ensures the AlwaysDefinedKeys are one of the optional key of the Opts type. That should help catch instances where we defined by mistake a default value for a mandatory option, or we mistakenly mark as required an option meant to be optional.
  3. Fix the resulting type errors in the codebase and tests.

Copy link
Contributor

Diff output files
diff --git a/packages/@uppy/xhr-upload/lib/index.js b/packages/@uppy/xhr-upload/lib/index.js
index a864f43..bb39afe 100644
--- a/packages/@uppy/xhr-upload/lib/index.js
+++ b/packages/@uppy/xhr-upload/lib/index.js
@@ -41,7 +41,6 @@ function setTypeInBlob(file) {
   return dataWithUpdatedType;
 }
 const defaultOptions = {
-  endpoint: "",
   formData: true,
   fieldName: "file",
   method: "post",

Comment on lines 94 to 106
export type ImageEditorOpts = Omit<
DefinePluginOpts<Opts, keyof typeof defaultOptions>,
'actions' | 'cropperOptions'
> & {
actions: DefinePluginOpts<
NonNullable<Opts['actions']>,
keyof typeof defaultActions
>
cropperOptions: DefinePluginOpts<
NonNullable<Opts['cropperOptions']>,
keyof typeof defaultCropperOptions
>
}
Copy link
Member

Choose a reason for hiding this comment

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

Can't we in this case remove the Partial's above so this type can stay simple? This seems a bit intense.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The issue is that we pass keyof typeof default…, so there's no way to validate the values of the object, only the keys. If there was a way to pass typeof default… instead, we would no longer need the satisfies above. I tried the following which didn't work (Type 'keyof DefaultValues' does not satisfy the constraint 'keyof Opts'.):

export type DefinePluginOpts<
  Opts,
  DefaultValues extends OnlyOptionals<Opts>,
> = Opts & Required<Pick<Opts, keyof DefaultValues>>

Copy link
Member

Choose a reason for hiding this comment

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

So you're saying this is only a problem because we have nested object types here with actions and such? The problem of "no way to validate the values of the object" is not present elsewhere?

Also, we are exporting the wrong type. ImageEditorOpts should be called Opts and not be exported and Opts should be called ImageEditorOpts and exported. We want to export the user facing type, not the internal type I think.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ImageEditorOpts should […] not be exported

Good catch, I've renamed it InternalImageEditorOpts.

So you're saying this is only a problem because we have nested object types here with actions and such? The problem of "no way to validate the values of the object" is not present elsewhere?

That's not what I'm saying, although having nested objects certainly makes the types more complicated.
Currently we need the satisfies to ensure the default values match the types of the associated option. Maybe there's a way to validate that somewhere else, in a more transparent way, but I wasn't able to find a way to do that.

Copy link
Member

Choose a reason for hiding this comment

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

I checked it out locally and and removed the Partial's and got no errors. Returning to the simple type of InternalImageEditorOpts also gave no errors. Where do we see the effect of this more complex type then?

Copy link
Contributor Author

@aduh95 aduh95 Jan 31, 2024

Choose a reason for hiding this comment

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

Well of course you won't see any error if you have looser types 🤷‍♂️ the idea is to have TS report when we use an incompatible type (i.e. you should test by changing the default value to something incompatible, e.g.
image)

Copy link
Contributor Author

@aduh95 aduh95 Jan 31, 2024

Choose a reason for hiding this comment

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

I misread your comment, I thought you removed the satisfies Partial<…>, but I guess what you meant is you replaced it with satisfies …; sorry for the confusion, my previous comment only addressed your second point.

You don't see any error because there are no required types in that options. We could indeed use the simpler type (i.e. without Partial<>), but:

  • if we ever end up adding a required option, we would get annoying TS error and need to go back and to wrap in Partial<>.
  • because we have required options in some plugins, it's more consistent to use Partial<> everywhere.

There might be a TS wizard out there that would be able to help us hide those satisfies into the DefinePluginOpts utility type, but I'm afraid that's out of my league.

Copy link
Member

@Murderlon Murderlon left a comment

Choose a reason for hiding this comment

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

nit: the exported type should be named ImageEditorOpts to be consistent with other plugin type export naming

There is also a build error. Then ready to go.

@aduh95 aduh95 merged commit 66bd526 into transloadit:main Feb 1, 2024
16 checks passed
@aduh95 aduh95 deleted the better-default-types branch February 1, 2024 13:06
@github-actions github-actions bot mentioned this pull request Feb 19, 2024
github-actions bot added a commit that referenced this pull request Feb 19, 2024
| Package                   | Version | Package                   | Version |
| ------------------------- | ------- | ------------------------- | ------- |
| @uppy/audio               |   1.1.5 | @uppy/remote-sources      |   1.1.1 |
| @uppy/aws-s3              |   3.6.1 | @uppy/status-bar          |   3.2.6 |
| @uppy/aws-s3-multipart    |  3.10.1 | @uppy/store-default       |   3.2.1 |
| @uppy/companion           |  4.12.1 | @uppy/store-redux         |   3.0.6 |
| @uppy/companion-client    |   3.7.1 | @uppy/svelte              |   3.1.2 |
| @uppy/compressor          |   1.1.0 | @uppy/thumbnail-generator |   3.0.7 |
| @uppy/core                |   3.9.0 | @uppy/transloadit         |   3.5.0 |
| @uppy/dashboard           |   3.7.2 | @uppy/tus                 |   3.5.1 |
| @uppy/drop-target         |   2.0.3 | @uppy/utils               |   5.7.1 |
| @uppy/form                |   3.1.0 | @uppy/vue                 |   1.1.1 |
| @uppy/golden-retriever    |   3.1.2 | @uppy/webcam              |   3.3.5 |
| @uppy/image-editor        |   2.4.1 | @uppy/xhr-upload          |   3.6.1 |
| @uppy/locales             |   3.5.1 | uppy                      |  3.22.0 |
| @uppy/provider-views      |   3.9.0 |                           |         |

-  @uppy/aws-s3-multipart,@uppy/aws-s3,@uppy/companion-client,@uppy/tus,@uppy/xhr-upload: update `uppyfile` objects before emitting events (antoine du hamel / #4928)
- @uppy/transloadit: add `clientname` option (marius / #4920)
- @uppy/thumbnail-generator: fix broken previews after cropping (evgenia karunus / #4926)
- @uppy/compressor: upgrade compressorjs (merlijn vos / #4924)
- @uppy/companion: fix companion dns and allow redirects from http->https again (mikael finstad / #4895)
- @uppy/dashboard: autoopenfileeditor - rename "edit file" to "edit image" (evgenia karunus / #4925)
- meta: resolve jsx to preact in shared tsconfig (merlijn vos / #4923)
- @uppy/image-editor: image editor: make compressor work after the image editor, too (evgenia karunus / #4918)
- meta: exclude `tsconfig` files from npm bundles (antoine du hamel / #4916)
- @uppy/compressor: migrate to ts (mikael finstad / #4907)
- @uppy/provider-views: update uppy-providerbrowser-viewtype--list.scss (aditya patadia / #4913)
- @uppy/tus: migrate to ts (merlijn vos / #4899)
- meta: bump yarn version (antoine du hamel / #4906)
- meta: validate `defaultoptions` for stricter option types (antoine du hamel / #4901)
- @uppy/dashboard: Uncouple native camera and video buttons from the `disableLocalFiles` option (jake mcallister / #4894)
- meta: put experimental ternaries in .prettierrc.js (merlijn vos / #4900)
- @uppy/xhr-upload: migrate to ts (merlijn vos / #4892)
- @uppy/drop-target: refactor to typescript (artur paikin / #4863)
- meta: fix missing line return in js2ts script (antoine du hamel)
- meta: disable `@typescript-eslint/no-empty-function` lint rule (antoine du hamel / #4891)
- @uppy/companion-client: fix tests and linter (antoine du hamel / #4890)
- @uppy/companion-client: migrate to ts (merlijn vos / #4864)
- meta: prettier 3.0.3 -> 3.2.4 (antoine du hamel / #4889)
- @uppy/image-editor: migrate to ts (merlijn vos / #4880)
- meta: fix race condition in `e2e.yml` (antoine du hamel)
- @uppy/core: add utility type to help define plugin option types (antoine du hamel / #4885)
- meta: merge `output-watcher` and `e2e` workflows (antoine du hamel / #4886)
- @uppy/status-bar: fix `statusbaroptions` type (antoine du hamel / #4883)
- @uppy/core: improve types of .use() (merlijn vos / #4882)
- @uppy/audio: fix `audiooptions` (antoine du hamel / #4884)
- meta: upgrade vite and vitest (antoine du hamel / #4881)
- meta: fix `yarn build:clean` (antoine du hamel)
- @uppy/audio: refactor to typescript (antoine du hamel / #4860)
- @uppy/status-bar: refactor to typescript (antoine du hamel / #4839)
- @uppy/core: add `plugintarget` type and mark options as optional (antoine du hamel / #4874)
- meta: improve output watcher diff (antoine du hamel / #4876)
- meta: minify the output watcher diff further (antoine du hamel)
- meta: remove comments from output watcher (mikael finstad / #4875)
- @uppy/utils: improve types for `finddomelement` (antoine du hamel / #4873)
- @uppy/code: allow plugins to type `pluginstate` (antoine du hamel / #4872)
- meta: build(deps): bump follow-redirects from 1.15.1 to 1.15.4 (dependabot[bot] / #4862)
- meta: add `output-watcher` gha to help check output diff (antoine du hamel / #4868)
- meta: generate locale pack from output file (antoine du hamel / #4867)
- meta: comment on what we want to do about close, resetprogress, clearuploadedfiles, etc in the next major (artur paikin / #4865)
- meta: fix `yarn build:clean` (antoine du hamel / #4866)
- meta: use `explicit-module-boundary-types` lint rule (antoine du hamel / #4858)
- @uppy/form: use requestsubmit (merlijn vos / #4852)
- @uppy/provider-views: add referrerpolicy to images (merlijn vos / #4853)
- @uppy/core: add `debuglogger` as export in manual types (antoine du hamel / #4831)
- meta: fix `js2ts` script (antoine du hamel / #4846)
- @uppy/xhr-upload: show remove button (merlijn vos / #4851)
- meta: upgrade `@transloadit/prettier-bytes` (antoine du hamel / #4850)
- @uppy/core: add missing requiredmetafields key in restrictions (darthf1 / #4819)
- @uppy/companion,@uppy/tus: bump `tus-js-client` version range (merlijn vos / #4848)
- meta: build(deps): bump aws/aws-sdk-php from 3.272.1 to 3.288.1 in /examples/aws-php (dependabot[bot] / #4838)
- @uppy/dashboard: fix `typeerror` when `file.remote` is nullish (antoine du hamel / #4825)
- meta: fix `js2ts` script (antoine du hamel / #4844)
- @uppy/locales: fix "save" button translation in hr_hr.ts (žan žlender / #4830)
- meta: fix linting of `.tsx` files (antoine du hamel / #4843)
- @uppy/core: fix types (antoine du hamel / #4842)
- @uppy/utils: improve `preprocess` and `postprocess` types (antoine du hamel / #4841)
- meta: fix `yarn build:clean` (mikael finstad / #4840)
- meta: dev: remove extensions from vite aliases (antoine du hamel)
- meta: fix `"e2e"` script (antoine du hamel)
- @uppy/core: refactor to ts (murderlon)
- meta: fix typescript ci (antoine du hamel)
- meta: fix clean script (mikael finstad / #4820)
- @uppy/companion-client: fix `typeerror` (antoine du hamel)
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