diff --git a/packages/core/package.json b/packages/core/package.json index ae758c9cf3..4544125bc4 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -35,6 +35,7 @@ "@types/google-protobuf": "^3.7.2", "@types/jest": "^24.0.0", "@types/node": "^12.0.0", + "@types/react-helmet": "^5.0.15", "@types/react-sparklines": "^1.7.0" }, "dependencies": { diff --git a/packages/core/src/api/apis/definitions/alert.ts b/packages/core/src/api/apis/definitions/alert.ts index f0d0bb3d72..133255c719 100644 --- a/packages/core/src/api/apis/definitions/alert.ts +++ b/packages/core/src/api/apis/definitions/alert.ts @@ -29,7 +29,7 @@ export type AlertApi = { /** * Post an alert for handling by the application. */ - post(alert: AlertMessage); + post(alert: AlertMessage): void; }; export const alertApiRef = new ApiRef({ diff --git a/packages/core/src/api/apis/definitions/error.ts b/packages/core/src/api/apis/definitions/error.ts index 01a6509715..f2a8509558 100644 --- a/packages/core/src/api/apis/definitions/error.ts +++ b/packages/core/src/api/apis/definitions/error.ts @@ -53,7 +53,7 @@ export type ErrorApi = { /** * Post an error for handling by the application. */ - post(error: Error, context?: ErrorContext); + post(error: Error, context?: ErrorContext): void; }; export const errorApiRef = new ApiRef({ diff --git a/packages/core/src/api/app/FeatureFlags.test.tsx b/packages/core/src/api/app/FeatureFlags.test.tsx index cc09ebc61d..38fe457781 100644 --- a/packages/core/src/api/app/FeatureFlags.test.tsx +++ b/packages/core/src/api/app/FeatureFlags.test.tsx @@ -15,7 +15,10 @@ */ import { FeatureFlags as FeatureFlagsImpl } from './FeatureFlags'; -import { FeatureFlagState } from 'api/apis/definitions/featureFlags'; +import { + FeatureFlagState, + FeatureFlagsApi, +} from 'api/apis/definitions/featureFlags'; describe('FeatureFlags', () => { beforeEach(() => { @@ -23,7 +26,7 @@ describe('FeatureFlags', () => { }); describe('#getFlags', () => { - let featureFlags; + let featureFlags: FeatureFlagsApi; beforeEach(() => { featureFlags = new FeatureFlagsImpl(); @@ -121,7 +124,7 @@ describe('FeatureFlags', () => { }); describe('#getRegisteredFlags', () => { - let featureFlags; + let featureFlags: FeatureFlagsApi; beforeEach(() => { featureFlags = new FeatureFlagsImpl(); @@ -146,7 +149,7 @@ describe('FeatureFlags', () => { }); it('should get the correct values', () => { - const getByName = name => + const getByName = (name: string) => featureFlags.getRegisteredFlags().find(flag => flag.name === name); expect(getByName('registered-flag-0')).toBeUndefined(); diff --git a/packages/core/src/components/CopyTextButton/CopyTextButton.stories.tsx b/packages/core/src/components/CopyTextButton/CopyTextButton.stories.tsx index 7fd78f8057..e8e1317e4e 100644 --- a/packages/core/src/components/CopyTextButton/CopyTextButton.stories.tsx +++ b/packages/core/src/components/CopyTextButton/CopyTextButton.stories.tsx @@ -16,13 +16,13 @@ import React from 'react'; import CopyTextButton from '.'; -import { ApiProvider, errorApiRef, ApiRegistry } from 'api'; +import { ApiProvider, errorApiRef, ApiRegistry, ErrorApi } from 'api'; export default { title: 'CopyTextButton', component: CopyTextButton, decorators: [ - storyFn => { + (storyFn: () => JSX.Element) => { // TODO: move this to common storybook config, requires core package to be separate from components const registry = ApiRegistry.from([ [ @@ -32,7 +32,7 @@ export default { // eslint-disable-next-line no-alert window.alert(`Component posted error, ${error}`); }, - }, + } as ErrorApi, ], ]); return ; diff --git a/packages/core/src/components/CopyTextButton/CopyTextButton.test.tsx b/packages/core/src/components/CopyTextButton/CopyTextButton.test.tsx index 2abf9d0622..28aaf2f0c0 100644 --- a/packages/core/src/components/CopyTextButton/CopyTextButton.test.tsx +++ b/packages/core/src/components/CopyTextButton/CopyTextButton.test.tsx @@ -18,7 +18,7 @@ import React from 'react'; import { render } from '@testing-library/react'; import { wrapInThemedTestApp } from '@backstage/test-utils'; import CopyTextButton from './CopyTextButton'; -import { ApiRegistry, errorApiRef, ApiProvider } from 'api'; +import { ApiRegistry, errorApiRef, ApiProvider, ErrorApi } from 'api'; jest.mock('popper.js', () => { const PopperJS = jest.requireActual('popper.js'); @@ -44,7 +44,7 @@ const apiRegistry = ApiRegistry.from([ post(error) { throw error; }, - }, + } as ErrorApi, ], ]); diff --git a/packages/core/src/components/CopyTextButton/CopyTextButton.tsx b/packages/core/src/components/CopyTextButton/CopyTextButton.tsx index 86c3778d26..62295eb0ce 100644 --- a/packages/core/src/components/CopyTextButton/CopyTextButton.tsx +++ b/packages/core/src/components/CopyTextButton/CopyTextButton.tsx @@ -14,7 +14,7 @@ * limitations under the License. */ -import React, { FC, useRef, useState } from 'react'; +import React, { FC, useRef, useState, MouseEventHandler } from 'react'; import { IconButton, makeStyles, Tooltip } from '@material-ui/core'; import PropTypes from 'prop-types'; import CopyIcon from '@material-ui/icons/FileCopy'; @@ -66,7 +66,7 @@ const CopyTextButton: FC = props => { const inputRef = useRef(null); const [open, setOpen] = useState(false); - const handleCopyClick = e => { + const handleCopyClick: MouseEventHandler = e => { e.stopPropagation(); setOpen(true); diff --git a/packages/core/src/components/ProgressBars/CircleProgress.tsx b/packages/core/src/components/ProgressBars/CircleProgress.tsx index b1f857d0ac..b2da573de3 100644 --- a/packages/core/src/components/ProgressBars/CircleProgress.tsx +++ b/packages/core/src/components/ProgressBars/CircleProgress.tsx @@ -55,7 +55,12 @@ const defaultProps = { max: 100, }; -export function getProgressColor(palette, value, inverse, max) { +export function getProgressColor( + palette: BackstageTheme['palette'], + value: number, + inverse?: boolean, + max?: number, +) { if (isNaN(value)) { return '#ddd'; } @@ -74,7 +79,7 @@ export function getProgressColor(palette, value, inverse, max) { const CircleProgress: FC = props => { const classes = useStyles(props); - const theme = useTheme(); + const theme = useTheme(); const { value, fractional, inverse, unit, max } = { ...defaultProps, ...props, diff --git a/packages/core/src/components/SortableTable/SortableTable.stories.tsx b/packages/core/src/components/SortableTable/SortableTable.stories.tsx index 3938916156..2a903e1df7 100644 --- a/packages/core/src/components/SortableTable/SortableTable.stories.tsx +++ b/packages/core/src/components/SortableTable/SortableTable.stories.tsx @@ -33,7 +33,11 @@ const data = [ const columns = [ { id: 'id', label: 'ID' }, { id: 'amount', disablePadding: false, numeric: true, label: 'AMOUNT' }, - { id: 'status', label: 'STATUS', sortValue: row => row.statusValue }, + { + id: 'status', + label: 'STATUS', + sortValue: (row: typeof data[0]) => row.statusValue, + }, ]; const footerData = [ { id: 'total', amount: 4, statusValue: 2, status: }, diff --git a/packages/core/src/components/StructuredMetadataTable/StructuredMetadataTable.stories.tsx b/packages/core/src/components/StructuredMetadataTable/StructuredMetadataTable.stories.tsx index 5a04520dd1..334219c881 100644 --- a/packages/core/src/components/StructuredMetadataTable/StructuredMetadataTable.stories.tsx +++ b/packages/core/src/components/StructuredMetadataTable/StructuredMetadataTable.stories.tsx @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import React from 'react'; +import React, { FC } from 'react'; import InfoCard from '../../layout/InfoCard'; import { Grid } from '@material-ui/core'; import StructuredMetadataTable from '.'; @@ -41,7 +41,7 @@ export default { component: StructuredMetadataTable, }; -const Wrapper = ({ children }) => ( +const Wrapper: FC<{}> = ({ children }) => ( {children} diff --git a/packages/core/src/components/SupportButton/SupportButton.tsx b/packages/core/src/components/SupportButton/SupportButton.tsx index 076ec2d3c9..c884086bfa 100644 --- a/packages/core/src/components/SupportButton/SupportButton.tsx +++ b/packages/core/src/components/SupportButton/SupportButton.tsx @@ -14,7 +14,7 @@ * limitations under the License. */ -import React, { FC, Fragment, useState } from 'react'; +import React, { FC, Fragment, useState, MouseEventHandler } from 'react'; import { Button, Link, @@ -58,10 +58,10 @@ const SupportButton: FC = ({ // TODO: get plugin manifest with hook const [popoverOpen, setPopoverOpen] = useState(false); - const [anchorEl, setAnchorEl] = useState(null); + const [anchorEl, setAnchorEl] = useState(null); const classes = useStyles(); - const onClickHandler = event => { + const onClickHandler: MouseEventHandler = event => { setAnchorEl(event.currentTarget); setPopoverOpen(true); }; diff --git a/packages/core/src/components/WarningPanel/WarningPanel.tsx b/packages/core/src/components/WarningPanel/WarningPanel.tsx index 1d3b3e03db..a3e6ed6c78 100644 --- a/packages/core/src/components/WarningPanel/WarningPanel.tsx +++ b/packages/core/src/components/WarningPanel/WarningPanel.tsx @@ -15,17 +15,20 @@ */ import React, { FC } from 'react'; -import { Typography, withStyles, makeStyles } from '@material-ui/core'; +import { Typography, makeStyles } from '@material-ui/core'; import { BackstageTheme } from '@backstage/theme'; import ErrorOutline from '@material-ui/icons/ErrorOutline'; -const errorOutlineStyles = theme => ({ +const useErrorOutlineStyles = makeStyles(theme => ({ root: { marginRight: theme.spacing(1), fill: theme.palette.warningText, }, -}); -const ErrorOutlineStyled = withStyles(errorOutlineStyles)(ErrorOutline); +})); +const ErrorOutlineStyled = () => { + const classes = useErrorOutlineStyles(); + return ; +}; const useStyles = makeStyles(theme => ({ message: { diff --git a/packages/core/src/layout/ContentHeader/ContentHeader.test.tsx b/packages/core/src/layout/ContentHeader/ContentHeader.test.tsx index 1ab171bcf1..6f5a1b24cc 100644 --- a/packages/core/src/layout/ContentHeader/ContentHeader.test.tsx +++ b/packages/core/src/layout/ContentHeader/ContentHeader.test.tsx @@ -20,7 +20,7 @@ import ContentHeader from './ContentHeader'; import { wrapInThemedTestApp } from '@backstage/test-utils'; jest.mock('react-helmet', () => { - return ({ defaultTitle }) =>
defaultTitle: {defaultTitle}
; + return ({ defaultTitle }: any) =>
defaultTitle: {defaultTitle}
; }); describe('', () => { diff --git a/packages/core/src/layout/ErrorBoundary/ErrorBoundary.tsx b/packages/core/src/layout/ErrorBoundary/ErrorBoundary.tsx index 9e9d639548..88ae99c3c9 100644 --- a/packages/core/src/layout/ErrorBoundary/ErrorBoundary.tsx +++ b/packages/core/src/layout/ErrorBoundary/ErrorBoundary.tsx @@ -14,7 +14,7 @@ * limitations under the License. */ -import React, { ComponentClass, Component, SFC } from 'react'; +import React, { ComponentClass, Component, SFC, ErrorInfo } from 'react'; type Props = { slackChannel?: string; @@ -23,14 +23,14 @@ type Props = { type State = { error?: Error; - errorInfo?: string; + errorInfo?: ErrorInfo; }; const ErrorBoundary: ComponentClass< Props, State > = class ErrorBoundary extends Component { - constructor(props) { + constructor(props: Props) { super(props); this.state = { @@ -39,15 +39,10 @@ const ErrorBoundary: ComponentClass< }; } - componentDidCatch(error, errorInfo) { + componentDidCatch(error: Error, errorInfo: ErrorInfo) { // eslint-disable-next-line no-console console.error(`ErrorBoundary, error: ${error}, info: ${errorInfo}`); this.setState({ error, errorInfo }); - - // Exposed for testing - if (this.props.onError) { - this.props.onError(error, errorInfo); - } } render() { @@ -58,9 +53,7 @@ const ErrorBoundary: ComponentClass< return this.props.children; } - return ( - - ); + return ; } }; @@ -68,7 +61,6 @@ export default ErrorBoundary; type EProps = { error?: Error; - errorInfo?: string; slackChannel?: string; }; diff --git a/packages/core/src/layout/Header/Header.test.tsx b/packages/core/src/layout/Header/Header.test.tsx index 79d74791c8..85b15e33aa 100644 --- a/packages/core/src/layout/Header/Header.test.tsx +++ b/packages/core/src/layout/Header/Header.test.tsx @@ -20,7 +20,7 @@ import { wrapInThemedTestApp } from '@backstage/test-utils'; import Header from './Header'; jest.mock('react-helmet', () => { - return ({ defaultTitle }) =>
defaultTitle: {defaultTitle}
; + return ({ defaultTitle }: any) =>
defaultTitle: {defaultTitle}
; }); describe('
', () => { diff --git a/packages/core/src/layout/InfoCard/InfoCard.stories.tsx b/packages/core/src/layout/InfoCard/InfoCard.stories.tsx index 611facd29c..e9fa831b40 100644 --- a/packages/core/src/layout/InfoCard/InfoCard.stories.tsx +++ b/packages/core/src/layout/InfoCard/InfoCard.stories.tsx @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import React from 'react'; +import React, { FC } from 'react'; import InfoCard from '.'; import { Grid } from '@material-ui/core'; @@ -25,7 +25,7 @@ export default { component: InfoCard, }; -const Wrapper = ({ children }) => ( +const Wrapper: FC<{}> = ({ children }) => ( {children} diff --git a/packages/core/src/layout/InfoCard/InfoCard.tsx b/packages/core/src/layout/InfoCard/InfoCard.tsx index f3d03d29c8..d645b25aaa 100644 --- a/packages/core/src/layout/InfoCard/InfoCard.tsx +++ b/packages/core/src/layout/InfoCard/InfoCard.tsx @@ -163,10 +163,15 @@ const InfoCard: FC = ({ if (variant) { const variants = variant.split(/[\s]+/g); variants.forEach(name => { - calculatedStyle = { ...calculatedStyle, ...VARIANT_STYLES.card[name] }; + calculatedStyle = { + ...calculatedStyle, + ...VARIANT_STYLES.card[name as keyof typeof VARIANT_STYLES['card']], + }; calculatedCardStyle = { ...calculatedCardStyle, - ...VARIANT_STYLES.cardContent[name], + ...VARIANT_STYLES.cardContent[ + name as keyof typeof VARIANT_STYLES['cardContent'] + ], }; }); } diff --git a/packages/core/src/layout/TabbedCard/TabbedCard.stories.tsx b/packages/core/src/layout/TabbedCard/TabbedCard.stories.tsx index cf9fa6e6c6..23c2ab5b49 100644 --- a/packages/core/src/layout/TabbedCard/TabbedCard.stories.tsx +++ b/packages/core/src/layout/TabbedCard/TabbedCard.stories.tsx @@ -23,7 +23,7 @@ export default { title: 'Tabbed Card', component: TabbedCard, decorators: [ - storyFn => ( + (storyFn: () => JSX.Element) => ( {storyFn()} @@ -72,9 +72,10 @@ export const WithFooterLink = () => { }; export const WithControlledTabValue = () => { - const [selectedTab, setSelectedTab] = useState('one'); + const [selectedTab, setSelectedTab] = useState('one'); - const handleChange = (_ev, newSelectedTab) => setSelectedTab(newSelectedTab); + const handleChange = (_ev: any, newSelectedTab: string | number) => + setSelectedTab(newSelectedTab); return ( <> diff --git a/packages/core/src/layout/TabbedCard/TabbedCard.tsx b/packages/core/src/layout/TabbedCard/TabbedCard.tsx index bd7443e924..4dd1399fb0 100644 --- a/packages/core/src/layout/TabbedCard/TabbedCard.tsx +++ b/packages/core/src/layout/TabbedCard/TabbedCard.tsx @@ -68,7 +68,7 @@ const TabbedCard: FC = ({ const handleChange = onChange ? onChange - : (_ev, newSelectedIndex: number) => selectIndex(newSelectedIndex); + : (_ev: unknown, newSelectedIndex: number) => selectIndex(newSelectedIndex); let selectedTabContent: ReactNode; if (!value) { diff --git a/packages/core/tsconfig.json b/packages/core/tsconfig.json index 5c5c42c25f..7b73db2f0f 100644 --- a/packages/core/tsconfig.json +++ b/packages/core/tsconfig.json @@ -2,7 +2,6 @@ "extends": "../../tsconfig.json", "include": ["src"], "compilerOptions": { - "baseUrl": "src", - "noImplicitAny": false + "baseUrl": "src" } }