[BUGFIX] improve component argument types for TS-JS interop #286
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Component
currently types its arguments as extending{}
:This works in pure-JS or pure-TS codebases, but breaks down in mixed codebases, especially where users are using the
@ts-check
pragma or where we want to feed information from component definitions into the TS language server to get better completion info throughout an app.For example, given this component in a JS codebase with
@ts-check
enabled:The TS language server (e.g. in an editor) will report:
To eliminate this problem while maintaining compatibility with all existing typed usages (including some we might like to forbid but cannot at present, like passing
Component<[]>
-- thanks JavaScript!), we switch from{}
toRecord<string, any>
:Now, the error described above is eliminated for JS consumers using TS information in any way, but TS users can continue to supply correct types for their components.
A note on
Record
, which was added in TS 2.1 (and see also the note on the handbook): using it safely requires explicitly calling out optional or nullable types. For example:It's our old friend:
Accordingly, most uses of
Record
should be of the formRecord<string, T | undefined>
, and a safeDict<T>
would be exactly that: