We use the following code to enable compile check and IntelliSense for our redux reducers:
It is in a .ts
file and not .tsx
(https://stackoverflow.com/a/45576880/3850405)
export function typedAction<T extends string>(type: T): { type: T };
export function typedAction<T extends string, P extends any>(
type: T,
payload: P
): { type: T; payload: P };
export function typedAction(type: string, payload?: any) {
return { type, payload };
}
This means that our reducers knows what Actions are available:
Sources:
https://levelup.gitconnected.com/set-up-a-typescript-react-redux-project-35d65f14b869
https://stackoverflow.com/a/61276522/3850405
If the below functions are removed no check is done:
export function typedAction<T extends string>(type: T): { type: T };
export function typedAction<T extends string, P extends any>(
type: T,
payload: P
): { type: T; payload: P };
The project recently decided to prefer arrow functions instead of function declarations.
https://www.npmjs.com/package/eslint-plugin-prefer-arrow
https://eslint.org/docs/rules/func-style
Our eslint config looks like this:
"plugins": [
"prefer-arrow"
],
"rules": {
"prefer-arrow/prefer-arrow-functions": [
"error",
{
"disallowPrototype": true,
"singleReturnOnly": false,
"classPropertiesAllowed": false
}
],
"prefer-arrow-callback": [
"error",
{ "allowNamedFunctions": true }
],
"func-style": [
"error",
"expression",
{ "allowArrowFunctions": true }
]
}
This meant that we got the following linting errors:
7:8 error Expected a function expression func-style
7:8 error Use const or class constructors instead of named functions prefer-arrow/prefer-arrow-functions
If the typedAction
function is converted to an arrow function the following errors are received:
export const typedAction = (type: string, payload?: any) => {
return { type, payload };
}
TS2300 (TS) Duplicate identifier 'typedAction'.
TS2391 (TS) Function implementation is missing or not immediately following the declaration.
To be able to continue it is solved like this but a more permanent solution would be preferable:
export function typedAction<T extends string>(type: T): { type: T };
export function typedAction<T extends string, P extends any>(
type: T,
payload: P
): { type: T; payload: P };
// eslint-disable-next-line func-style, prefer-arrow/prefer-arrow-functions
export function typedAction(type: string, payload?: any) {
return { type, payload };
}