diff --git a/.changeset/weak-oranges-give.md b/.changeset/weak-oranges-give.md new file mode 100644 index 0000000000..9e24244fcb --- /dev/null +++ b/.changeset/weak-oranges-give.md @@ -0,0 +1,8 @@ +--- +'@backstage/core-plugin-api': patch +'@backstage/plugin-scaffolder-react': patch +'@backstage/plugin-scaffolder-node': patch +'@backstage/plugin-catalog-react': patch +--- + +Minor type tweaks for TypeScript 5.0 diff --git a/packages/cli/src/lib/new/FactoryRegistry.ts b/packages/cli/src/lib/new/FactoryRegistry.ts index 9072d46c4c..d16aa0615a 100644 --- a/packages/cli/src/lib/new/FactoryRegistry.ts +++ b/packages/cli/src/lib/new/FactoryRegistry.ts @@ -15,12 +15,12 @@ */ import chalk from 'chalk'; -import inquirer from 'inquirer'; +import inquirer, { Answers } from 'inquirer'; import { AnyFactory, Prompt } from './types'; import * as factories from './factories'; import partition from 'lodash/partition'; -function applyPromptMessageTransforms( +function applyPromptMessageTransforms( prompt: Prompt, transforms: { message: (msg: string) => string; diff --git a/packages/cli/src/lib/new/types.ts b/packages/cli/src/lib/new/types.ts index 5a2460d0df..6a894bf9ef 100644 --- a/packages/cli/src/lib/new/types.ts +++ b/packages/cli/src/lib/new/types.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { DistinctQuestion } from 'inquirer'; +import { Answers, DistinctQuestion } from 'inquirer'; export interface CreateContext { /** The package scope to use for new packages */ @@ -37,7 +37,9 @@ export interface CreateContext { export type AnyOptions = Record; -export type Prompt = DistinctQuestion & { name: string }; +export type Prompt = DistinctQuestion & { + name: string; +}; export interface Factory { /** diff --git a/packages/core-components/src/components/Table/Table.tsx b/packages/core-components/src/components/Table/Table.tsx index c43345c9d2..848c85eb60 100644 --- a/packages/core-components/src/components/Table/Table.tsx +++ b/packages/core-components/src/components/Table/Table.tsx @@ -376,7 +376,7 @@ export function Table(props: TableProps) { const newData = (data as any[]).filter( el => !!Object.entries(selectedFilters) - .filter(([, value]) => !!value.length) + .filter(([, value]) => !!(value as { length?: number }).length) .every(([key, filterValue]) => { const fieldValue = extractValueByField( el, diff --git a/packages/core-plugin-api/src/analytics/AnalyticsContext.tsx b/packages/core-plugin-api/src/analytics/AnalyticsContext.tsx index f28444db46..105be8e2b5 100644 --- a/packages/core-plugin-api/src/analytics/AnalyticsContext.tsx +++ b/packages/core-plugin-api/src/analytics/AnalyticsContext.tsx @@ -91,11 +91,11 @@ export const AnalyticsContext = (options: { * @param values - Analytics context key/value pairs. * @internal */ -export function withAnalyticsContext

( - Component: React.ComponentType

, +export function withAnalyticsContext( + Component: React.ComponentType, values: AnalyticsContextValue, ) { - const ComponentWithAnalyticsContext = (props: P) => { + const ComponentWithAnalyticsContext = (props: TProps) => { return ( diff --git a/packages/core-plugin-api/src/apis/system/useApi.tsx b/packages/core-plugin-api/src/apis/system/useApi.tsx index 465a39cff4..03c4fa33ac 100644 --- a/packages/core-plugin-api/src/apis/system/useApi.tsx +++ b/packages/core-plugin-api/src/apis/system/useApi.tsx @@ -58,11 +58,11 @@ export function useApi(apiRef: ApiRef): T { * @param apis - APIs for the context. * @public */ -export function withApis(apis: TypesToApiRefs) { - return function withApisWrapper

( - WrappedComponent: React.ComponentType

, +export function withApis(apis: TypesToApiRefs) { + return function withApisWrapper( + WrappedComponent: React.ComponentType, ) { - const Hoc = (props: PropsWithChildren>) => { + const Hoc = (props: PropsWithChildren>) => { const apiHolder = useApiHolder(); const impls = {} as T; @@ -79,7 +79,7 @@ export function withApis(apis: TypesToApiRefs) { } } - return ; + return ; }; const displayName = WrappedComponent.displayName || WrappedComponent.name || 'Component'; diff --git a/packages/test-utils/src/testUtils/apis/StorageApi/MockStorageApi.ts b/packages/test-utils/src/testUtils/apis/StorageApi/MockStorageApi.ts index 6ce91a4a31..30d523aed2 100644 --- a/packages/test-utils/src/testUtils/apis/StorageApi/MockStorageApi.ts +++ b/packages/test-utils/src/testUtils/apis/StorageApi/MockStorageApi.ts @@ -101,7 +101,9 @@ export class MockStorageApi implements StorageApi { }); } - observe$(key: string): Observable> { + observe$( + key: string, + ): Observable> { return this.observable.filter(({ key: messageKey }) => messageKey === key); } @@ -109,7 +111,7 @@ export class MockStorageApi implements StorageApi { return `${this.namespace}/${encodeURIComponent(key)}`; } - private notifyChanges(message: StorageValueSnapshot) { + private notifyChanges(message: StorageValueSnapshot) { for (const subscription of this.subscribers) { subscription.next(message); } diff --git a/packages/test-utils/src/testUtils/appWrappers.tsx b/packages/test-utils/src/testUtils/appWrappers.tsx index 6543f8b698..8b644ad2d1 100644 --- a/packages/test-utils/src/testUtils/appWrappers.tsx +++ b/packages/test-utils/src/testUtils/appWrappers.tsx @@ -208,7 +208,7 @@ export function wrapInTestApp( let wrappedElement: React.ReactElement; if (Component instanceof Function) { - wrappedElement = ; + wrappedElement = React.createElement(Component as ComponentType); } else { wrappedElement = Component as React.ReactElement; } @@ -233,7 +233,7 @@ export async function renderInTestApp( ): Promise { let wrappedElement: React.ReactElement; if (Component instanceof Function) { - wrappedElement = ; + wrappedElement = React.createElement(Component as ComponentType); } else { wrappedElement = Component as React.ReactElement; } diff --git a/plugins/catalog-react/src/components/EntityAutocompletePicker/EntityAutocompletePicker.tsx b/plugins/catalog-react/src/components/EntityAutocompletePicker/EntityAutocompletePicker.tsx index b81d681e6d..15e44baf20 100644 --- a/plugins/catalog-react/src/components/EntityAutocompletePicker/EntityAutocompletePicker.tsx +++ b/plugins/catalog-react/src/components/EntityAutocompletePicker/EntityAutocompletePicker.tsx @@ -114,8 +114,9 @@ export function EntityAutocompletePicker< } as Partial); }, [name, shouldAddFilter, selectedOptions, Filter, updateFilters]); + const filter = filters[name]; if ( - (filters[name] && !('values' in filters[name])) || + (filter && typeof filter === 'object' && !('values' in filter)) || !availableOptions.length ) { return null; diff --git a/plugins/catalog-react/src/components/EntityRefLink/FetchedEntityRefLinks.tsx b/plugins/catalog-react/src/components/EntityRefLink/FetchedEntityRefLinks.tsx index ea4a32b511..d8f013d50c 100644 --- a/plugins/catalog-react/src/components/EntityRefLink/FetchedEntityRefLinks.tsx +++ b/plugins/catalog-react/src/components/EntityRefLink/FetchedEntityRefLinks.tsx @@ -57,11 +57,14 @@ export function FetchedEntityRefLinks< error, } = useAsync(async () => { const refs = entityRefs.reduce((acc, current) => { - return 'metadata' in current ? acc : [...acc, parseEntityRef(current)]; + if (typeof current === 'object' && 'metadata' in current) { + return acc; + } + return [...acc, parseEntityRef(current)]; }, new Array()); const pureEntities = entityRefs.filter( - ref => 'metadata' in ref, + ref => typeof ref === 'object' && 'metadata' in ref, ) as Array; return refs.length > 0 diff --git a/plugins/catalog-react/src/hooks/useEntityListProvider.tsx b/plugins/catalog-react/src/hooks/useEntityListProvider.tsx index a2b680c02e..4173724ef5 100644 --- a/plugins/catalog-react/src/hooks/useEntityListProvider.tsx +++ b/plugins/catalog-react/src/hooks/useEntityListProvider.tsx @@ -161,8 +161,9 @@ export const EntityListProvider = ( const queryParams = Object.keys(requestedFilters).reduce( (params, key) => { - const filter: EntityFilter | undefined = - requestedFilters[key as keyof EntityFilters]; + const filter = requestedFilters[key as keyof EntityFilters] as + | EntityFilter + | undefined; if (filter?.toQueryValue) { params[key] = filter.toQueryValue(); } diff --git a/plugins/cicd-statistics/src/charts/logic/daily-summary.ts b/plugins/cicd-statistics/src/charts/logic/daily-summary.ts index 93c7b07c34..f2ccf9d34c 100644 --- a/plugins/cicd-statistics/src/charts/logic/daily-summary.ts +++ b/plugins/cicd-statistics/src/charts/logic/daily-summary.ts @@ -70,10 +70,14 @@ function countTriggersPerDay(builds: ReadonlyArray) { const values = Object.entries(days).map(([epoch, buildsThisDay]) => { const datapoint = Object.fromEntries( triggerReasons - .map(reason => [ - reason, - buildsThisDay.filter(build => build.triggeredBy === reason).length, - ]) + .map( + reason => + [ + reason, + buildsThisDay.filter(build => build.triggeredBy === reason) + .length, + ] as const, + ) .filter(([_type, count]) => count > 0), ) as Omit; diff --git a/plugins/entity-feedback/src/components/StarredRatingButtons/StarredRatingButtons.tsx b/plugins/entity-feedback/src/components/StarredRatingButtons/StarredRatingButtons.tsx index 51f7da1099..75ad21a658 100644 --- a/plugins/entity-feedback/src/components/StarredRatingButtons/StarredRatingButtons.tsx +++ b/plugins/entity-feedback/src/components/StarredRatingButtons/StarredRatingButtons.tsx @@ -134,7 +134,7 @@ export const StarredRatingButtons = (props: StarredRatingButtonsProps) => { return ( <> {Object.values(FeedbackRatings) - .filter(o => typeof o === 'number') + .filter((o): o is number => typeof o === 'number') .map(starRating => ( issuesByRepository && activeFilter.length - ? activeFilter.reduce( + ? activeFilter.reduce( (acc, val) => ({ [val]: issuesByRepository[val], ...acc, diff --git a/plugins/playlist/src/hooks/usePlaylistList.tsx b/plugins/playlist/src/hooks/usePlaylistList.tsx index 69f712413b..b20f82bb5c 100644 --- a/plugins/playlist/src/hooks/usePlaylistList.tsx +++ b/plugins/playlist/src/hooks/usePlaylistList.tsx @@ -172,8 +172,9 @@ export const PlaylistListProvider = < const queryParams = Object.keys(requestedFilters).reduce( (params, key) => { - const filter: PlaylistFilter | undefined = - requestedFilters[key as keyof PlaylistFilters]; + const filter = requestedFilters[key as keyof PlaylistFilters] as + | PlaylistFilter + | undefined; if (filter?.toQueryValue) { params[key] = filter.toQueryValue(); } diff --git a/plugins/rollbar-backend/src/api/RollbarApi.ts b/plugins/rollbar-backend/src/api/RollbarApi.ts index 59394d7ad0..6bbf25eb8e 100644 --- a/plugins/rollbar-backend/src/api/RollbarApi.ts +++ b/plugins/rollbar-backend/src/api/RollbarApi.ts @@ -104,7 +104,7 @@ export class RollbarApi { ); } - private async get(url: string, accessToken?: string) { + private async get(url: string, accessToken?: string) { const fullUrl = buildUrl(url); if (this.logger) { @@ -119,7 +119,7 @@ export class RollbarApi { .then(json => camelcaseKeys(json?.result, { deep: true })); } - private async getForProject( + private async getForProject( url: string, projectName: string, useProjectToken = true, diff --git a/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.test.ts b/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.test.ts index e8698b62f5..b8c9edaae7 100644 --- a/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.test.ts @@ -120,7 +120,7 @@ describe('DefaultWorkflowRunner', () => { foo: z.number(), }), }, - }) as TemplateAction, + }) as TemplateAction, ); actionRegistry.register({ diff --git a/plugins/scaffolder-node/src/actions/createTemplateAction.ts b/plugins/scaffolder-node/src/actions/createTemplateAction.ts index 25c0dead55..a667f91744 100644 --- a/plugins/scaffolder-node/src/actions/createTemplateAction.ts +++ b/plugins/scaffolder-node/src/actions/createTemplateAction.ts @@ -22,8 +22,8 @@ import { JsonObject } from '@backstage/types'; /** @public */ export type TemplateActionOptions< - TActionInput = {}, - TActionOutput = {}, + TActionInput extends JsonObject = {}, + TActionOutput extends JsonObject = {}, TInputSchema extends Schema | z.ZodType = {}, TOutputSchema extends Schema | z.ZodType = {}, > = { @@ -48,10 +48,18 @@ export const createTemplateAction = < TOutputParams extends JsonObject = JsonObject, TInputSchema extends Schema | z.ZodType = {}, TOutputSchema extends Schema | z.ZodType = {}, - TActionInput = TInputSchema extends z.ZodType + TActionInput extends JsonObject = TInputSchema extends z.ZodType< + any, + any, + infer IReturn + > ? IReturn : TInputParams, - TActionOutput = TOutputSchema extends z.ZodType + TActionOutput extends JsonObject = TOutputSchema extends z.ZodType< + any, + any, + infer IReturn + > ? IReturn : TOutputParams, >( diff --git a/plugins/scaffolder-node/src/actions/types.ts b/plugins/scaffolder-node/src/actions/types.ts index 259773f1c0..e35f55aa67 100644 --- a/plugins/scaffolder-node/src/actions/types.ts +++ b/plugins/scaffolder-node/src/actions/types.ts @@ -75,8 +75,8 @@ export type ActionContext< /** @public */ export type TemplateAction< - TActionInput = unknown, - TActionOutput = JsonObject, + TActionInput extends JsonObject = JsonObject, + TActionOutput extends JsonObject = JsonObject, > = { id: string; description?: string; diff --git a/plugins/scaffolder-react/src/extensions/types.ts b/plugins/scaffolder-react/src/extensions/types.ts index a9ed854afa..5d560a20bc 100644 --- a/plugins/scaffolder-react/src/extensions/types.ts +++ b/plugins/scaffolder-react/src/extensions/types.ts @@ -64,7 +64,7 @@ export type FieldExtensionOptions< */ export interface FieldExtensionComponentProps< TFieldReturnValue, - TUiOptions extends {} = {}, + TUiOptions = unknown, > extends FieldProps { uiSchema: FieldProps['uiSchema'] & { 'ui:options'?: TUiOptions; diff --git a/plugins/sonarqube/dev/index.tsx b/plugins/sonarqube/dev/index.tsx index 8d38c7314a..33a36bcaef 100644 --- a/plugins/sonarqube/dev/index.tsx +++ b/plugins/sonarqube/dev/index.tsx @@ -66,9 +66,6 @@ createDevApp() - - - @@ -79,7 +76,7 @@ createDevApp() deps: {}, factory: () => ({ - getFindingSummary: async componentKey => { + getFindingSummary: async ({ componentKey }) => { switch (componentKey) { case 'error': throw new Error('Error!'); diff --git a/plugins/stack-overflow/src/home/StackOverflowQuestions/Content.tsx b/plugins/stack-overflow/src/home/StackOverflowQuestions/Content.tsx index 8fce24bd22..8d8aeccb3b 100644 --- a/plugins/stack-overflow/src/home/StackOverflowQuestions/Content.tsx +++ b/plugins/stack-overflow/src/home/StackOverflowQuestions/Content.tsx @@ -59,7 +59,7 @@ export const Content = (props: StackOverflowQuestionsContentProps) => { return could not load questions; } - const getSecondaryText = (answer_count: Number) => + const getSecondaryText = (answer_count: number) => answer_count > 1 ? `${answer_count} answers` : `${answer_count} answer`; return (