The interpolation function used for extracting theme data from props yields a "Missing return type on function." eslint error. I have used declaration merging to type my theme data as explained in typescript documentation. The merging seems to work correctly because props.theme
is typed according to my declarations.
The problem can be fixed by specifying a return type for the interpolation function
${(props): string => props.theme.colors.secondary}
but I don't think that should be necessary because I have already specified the type of props.theme.colors.secondary
in the type declarations file. Furthermore, in the vs code error popup it seems that the return type is known (function(...): string
), but the error is still given.
Code in GitHub.
// App.tsx
import React from 'react';
import styled, { ThemeProvider } from 'styled-components';
import theme from 'theme/default';
const StyledApp = styled.div`
// The error is caused by this interpolator function
background-color: ${(props) => props.theme.colors.secondary};
`;
// styled.d.ts
import 'styled-components';
// Extend the default theme type
declare module 'styled-components' {
export interface DefaultTheme {
colors: {
primary: string;
primaryLight: string;
primaryLighter: string;
primaryDark: string;
secondary: string;
secondaryLight: string;
secondaryDark: string;
font: string;
};
}
}
// theme/default.tsx
import { DefaultTheme } from 'styled-components';
const theme: DefaultTheme = {
colors: {
primary: 'hsl(0, 98%, 33%)',
primaryLight: 'hsl(359, 98%, 41%)',
primaryLighter: 'hsl(14, 54%, 52%)',
primaryDark: 'hsl(2, 90%, 20%)',
secondary: 'hsl(260, 4%, 31%)',
secondaryLight: 'hsl(35, 13%, 45%)',
secondaryDark: 'hsl(0, 14%, 1%)',
font: 'hsl(317, 7%, 79%)'
}
};
export default theme;
// .eslintrc.js
module.exports = {
env: {
browser: true
},
parser: '@typescript-eslint/parser',
extends: [
'airbnb',
'airbnb/hooks',
'plugin:@typescript-eslint/recommended',
'prettier/@typescript-eslint',
'plugin:prettier/recommended'
],
parserOptions: {
ecmaVersion: 2020,
sourceType: 'module'
},
rules: {
'react/jsx-filename-extension': [1, { extensions: ['.jsx', '.tsx'] }],
'react/prop-types': 'off'
},
settings: {
'import/extensions': ['.js', '.jsx', '.ts', '.tsx'],
'import/parsers': {
'@typescript-eslint/parser': ['.ts', '.tsx']
},
'import/resolver': {
node: {
paths: 'src',
extensions: ['.js', '.jsx', '.ts', '.tsx']
}
}
}
};
// tsconfig.json
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react",
"baseUrl": "src"
},
"include": ["src"]
}
// deps
"@types/react": "16.9.2",
"@types/react-dom": "16.9.0",
"@types/styled-components": "^4.1.18",
"overmind": "^19.1.1",
"react": "^16.9.0",
"react-dom": "^16.9.0",
"react-scripts": "3.1.1",
"styled-components": "^4.3.2",
"typescript": "3.6.2"
"@typescript-eslint/eslint-plugin": "^2.1.0",
"@typescript-eslint/parser": "^2.1.0",
"babel-core": "^7.0.0-bridge.0",
"eslint": "^6.1.0",
"eslint-config-airbnb": "^18.0.1",
"eslint-config-prettier": "^6.2.0",
"eslint-plugin-import": "^2.18.2",
"eslint-plugin-jsx-a11y": "^6.2.3",
"eslint-plugin-prettier": "^3.1.0",
"eslint-plugin-react": "^7.14.3",
"eslint-plugin-react-hooks": "^1.7.0",
"prettier": "^1.18.2"
I was able to fix the problem by adding the following rule to my .eslintrc.js
'@typescript-eslint/explicit-function-return-type': [
'error',
{
allowExpressions: true
}
]
It allows function expressions to not have an explicitely defined return type, which removes the missing return type error from styled components' interpolator functions as they are funcion expressions.
This solution simply turns the error off instead of fixing it directly.