reactjs - Egenskap finns inte på React-komponent när den definieras med recompose
Jag använder create-react-app med TypeScript-skripten som grund, och försöker få ett enkelt exempel att fungera med recompose.
Problemet är att jag inte kan skicka ner en egenskap direkt till komponenten.
Jag har skapat en enkel användarkomponent ./components/User.tsx:
import * as React from 'react';
import { compose, withState, withHandlers } from 'recompose';
export interface WithStateProps {
counter: number
setCounter: (x: (c: number) => number) => void;
}
export interface WithHandlerProps {
increment: () => void
decrement: () => void
}
interface ComponentProps {
name: string
}
export type ComposedProps = WithStateProps & WithHandlerProps
export type UserProps = ComposedProps & ComponentProps
export const enhance = compose<UserProps, {}>(
withState<WithStateProps, number, 'counter', 'setCounter'>('counter', 'setCounter', 1),
withHandlers<UserProps, UserProps>({
increment: ({ setCounter }) => () => setCounter( n => n + 1 ),
decrement: ({ setCounter }) => () => setCounter( n => n - 1 )
})
)
const User: React.StatelessComponent<UserProps> = ({counter, increment, decrement, name}: UserProps) => (
<div className='User'>
{name} : counter : {counter}
<div>
<button onClick={increment}> add </button>
<button onClick={decrement}> remove </button>
</div>
</div>
)
export default enhance(User)
Jag använder det i index.tsx:
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import registerServiceWorker from './registerServiceWorker';
import './index.css';
import User from './components/User'
import { createStore } from 'redux';
import { enthusiasm } from './reducers/index';
import { StoreState } from './types/index';
const store = createStore<StoreState>(enthusiasm, {
enthusiasmLevel: 1,
languageName: 'TypeScript',
});
ReactDOM.render(
<Provider store={store}>
<div>
<User />
</div>
</Provider>,
document.getElementById('root') as HTMLElement
);
registerServiceWorker();
Ovanstående fungerar bra, men om jag istället använder följande:
<User name='andrew hopkins' />
Jag får följande felmeddelande:
./src/index.tsx
(22,13): error TS2339: Property 'name' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes<Component<{}, ComponentState>> & Readonly<{ childr...'.
Min package.json-fil:
{
"name": "ts-rxjs-recompose",
"version": "0.1.0",
"private": true,
"dependencies": {
"react": "^16.0.0",
"react-dom": "^16.0.0",
"react-redux": "^5.0.6",
"react-scripts-ts": "2.7.0",
"recompose": "^0.25.1",
"redux": "^3.7.2"
},
"scripts": {
"start": "react-scripts-ts start",
"build": "react-scripts-ts build",
"test": "react-scripts-ts test --env=jsdom",
"eject": "react-scripts-ts eject"
},
"devDependencies": {
"@types/enzyme": "^2.8.9",
"@types/jest": "^21.1.1",
"@types/node": "^8.0.31",
"@types/react": "^16.0.7",
"@types/react-dom": "^15.5.5",
"@types/react-redux": "^5.0.9",
"@types/recompose": "^0.24.2",
"enzyme": "^3.0.0",
"react-addons-test-utils": "^15.6.2"
}
}
Svar #1
Lösningen var att använda ComponentProps för TOutter-typen för att komponera:
export const enhance = compose<UserProps, ComponentProps>(Detta beror på, när man tittar på typdefinitionen för compose
export function compose<TInner, TOutter>(
...functions: Function[]
): ComponentEnhancer<TInner, TOutter>;
Jag skickade igenom UserProps som TInner, men ett tomt objekt för TOutter, förbättrad, komponent, vilket orsakar felet.
REDIGERA: För att utveckla svaret är TOutter typen för den yttre komponenten, som i det här fallet är den som kommer att ta emot name-props, det vill säga <User />-komponenten som används i index.tsx. TInner förväntar sig en typ för den inre komponenten som kommer att ta emot alla props som skapats med recompose, i det här fallet User-komponenten inom ./components/User.tsx.
