Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/core/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ declare module '@rjsf/core' {

export function withTheme<T = any>(
themeProps: ThemeProps<T>,
): React.ComponentClass<FormProps<T>> | React.StatelessComponent<FormProps<T>>;
): React.ForwardRefExoticComponent<React.PropsWithoutRef<FormProps<T>> & React.RefAttributes<Form<T>>>;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This typing isn't actually correct.

the actual return type here is actually more like

React.ForwardRefExoticComponent<React.PropsWithoutRef<FormProps> & React.RefAttributes<Form>>;

however, there's no way to handle this with the type system and the types of React.ForwardRefExoticComponent.

This will basically always make the

a <Form /> component, forwarding an any to the formData prop (always).

I suggested in #2279 (before seeing this pr) that returning typeof Form here might be a solution that aligns the resulting types more correctly with the function here?

Copy link
Copy Markdown
Contributor Author

@zepatrik zepatrik Mar 22, 2021

Choose a reason for hiding this comment

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

Isn't FormProps generic? Why not pass down the generic just like I did? Your proposal

React.ForwardRefExoticComponent<React.PropsWithoutRef<FormProps> & React.RefAttributes<Form>>;

is just the same as my proposal, but without the generic?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Btw, I also added the types test https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/react-jsonschema-form/react-jsonschema-form-tests.tsx to see the effect of my changes. Maybe you can point to the test cases where you think the typing is wrong?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@zepatrik will try to get a look at those tests in a little bit.

yes, FormProps is generic the issue is that

export function withTheme<T = any>(
        themeProps: ThemeProps<T>,
    ): React.ForwardRefExoticComponent<React.PropsWithoutRef<FormProps<T>> & React.RefAttributes<Form<T>>>;

this code uses T from the theme props as the value for the generic, when what's actually produced is a generic forward ref that takes some new type FormDataType (because I really don't like using T and U everywhere :-D) and a resulting <FormDataType>React.ForwardRefExoticComponent<React.PropsWithoutRef<FormProps<FormDataType>> & React.RefAttributes<Form<FormDataType>>> would be more correct, however to my knowledge, based on how ForwardRefExoticComponent is defined, it's impossible to return this from the withTheme function

The Form resulting from withTheme should accept a generic, not re-use the generic from withTheme.

returning typeof Form acts as though it's returning the generic class class Form<FormDataType> extend React.Component<FormDataType>, which maintains the ability to pass the formData generic into <WithThemedForm<FormDataType> />, which the current typings with ForwardRefExoticComponent cannot support


export type AddButtonProps = {
className: string;
Expand Down
39 changes: 25 additions & 14 deletions packages/core/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@
"publish-to-npm": "npm run build && npm publish",
"start": "concurrently \"npm:build:* -- --watch\"",
"tdd": "cross-env NODE_ENV=test mocha --require @babel/register --watch --require ./test/setup-jsdom.js test/**/*_test.js",
"test": "cross-env BABEL_ENV=test NODE_ENV=test mocha --require @babel/register --require ./test/setup-jsdom.js test/**/*_test.js",
"test": "concurrently \"cross-env BABEL_ENV=test NODE_ENV=test mocha --require @babel/register --require ./test/setup-jsdom.js test/**/*_test.js\" \"npm:test-type\"",
"test-coverage": "cross-env NODE_ENV=test nyc --reporter=lcov mocha --require @babel/register --require ./test/setup-jsdom.js test/**/*_test.js",
"test-debug": "cross-env NODE_ENV=test mocha --require @babel/register --require ./test/setup-jsdom.js --debug-brk --inspect test/Form_test.js"
"test-debug": "cross-env NODE_ENV=test mocha --require @babel/register --require ./test/setup-jsdom.js --debug-brk --inspect test/Form_test.js",
"test-type": "tsc"
},
"lint-staged": {
"{src,test}/**/*.js": [
Expand Down Expand Up @@ -105,6 +106,7 @@
"rimraf": "^2.5.4",
"sinon": "^9.0.2",
"style-loader": "^0.13.1",
"typescript": "^4.2.3",
"webpack": "^4.42.1",
"webpack-cli": "^3.1.2",
"webpack-dev-middleware": "^3.4.0",
Expand Down
25 changes: 25 additions & 0 deletions packages/core/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"compilerOptions": {
"module": "commonjs",
"lib": [
"es6",
"dom"
],
"noImplicitAny": true,
"noImplicitThis": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"baseUrl": "../",
"typeRoots": [
"../"
],
"types": [],
"noEmit": true,
"forceConsistentCasingInFileNames": true,
"jsx": "react"
},
"files": [
"index.d.ts",
"typing_test.tsx"
]
}
Loading