diff --git a/src/ROUTES.ts b/src/ROUTES.ts index 31c2af8f4e58..77b5ffd2c80f 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -1,6 +1,7 @@ -import type {IsEqual, ValueOf} from 'type-fest'; +import type {ValueOf} from 'type-fest'; import type CONST from './CONST'; import type {IOURequestType} from './libs/actions/IOU'; +import type AssertTypesNotEqual from './types/utils/AssertTypesNotEqual'; // This is a file containing constants for all the routes we want to be able to go to @@ -730,20 +731,18 @@ export default ROUTES; // eslint-disable-next-line @typescript-eslint/no-explicit-any type ExtractRouteName = TRoute extends {getRoute: (...args: any[]) => infer TRouteName} ? TRouteName : TRoute; -type AllRoutes = { +/** + * Represents all routes in the app as a union of literal strings. + */ +type Route = { [K in keyof typeof ROUTES]: ExtractRouteName<(typeof ROUTES)[K]>; }[keyof typeof ROUTES]; -type RouteIsPlainString = IsEqual; +type RoutesValidationError = 'Error: One or more routes defined within `ROUTES` have not correctly used `as const` in their `getRoute` function return value.'; -/** - * Represents all routes in the app as a union of literal strings. - * - * If this type resolves to `never`, it implies that one or more routes defined within `ROUTES` have not correctly used - * `as const` in their `getRoute` function return value. - */ -type Route = RouteIsPlainString extends true ? never : AllRoutes; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +type RouteIsPlainString = AssertTypesNotEqual; type HybridAppRoute = (typeof HYBRID_APP_ROUTES)[keyof typeof HYBRID_APP_ROUTES]; -export type {Route, HybridAppRoute, AllRoutes}; +export type {Route, HybridAppRoute}; diff --git a/src/components/MoneyRequestConfirmationList.tsx b/src/components/MoneyRequestConfirmationList.tsx index 64c424e944f6..cadad07b6585 100755 --- a/src/components/MoneyRequestConfirmationList.tsx +++ b/src/components/MoneyRequestConfirmationList.tsx @@ -26,7 +26,7 @@ import * as TransactionUtils from '@libs/TransactionUtils'; import * as IOU from '@userActions/IOU'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import type {AllRoutes} from '@src/ROUTES'; +import type {Route} from '@src/ROUTES'; import ROUTES from '@src/ROUTES'; import type * as OnyxTypes from '@src/types/onyx'; import type {Participant} from '@src/types/onyx/IOU'; @@ -122,7 +122,7 @@ type MoneyRequestConfirmationListProps = MoneyRequestConfirmationListOnyxProps & isReadOnly?: boolean; /** Depending on expense report or personal IOU report, respective bank account route */ - bankAccountRoute?: AllRoutes; + bankAccountRoute?: Route; /** The policyID of the request */ policyID?: string; diff --git a/src/types/utils/AssertTypesNotEqual.ts b/src/types/utils/AssertTypesNotEqual.ts new file mode 100644 index 000000000000..237f54ec2921 --- /dev/null +++ b/src/types/utils/AssertTypesNotEqual.ts @@ -0,0 +1,11 @@ +import type {IsEqual} from 'type-fest'; + +type MatchError = 'Error: Types do match'; + +/** + * The 'AssertTypesNotEqual' type here enforces that `T1` and `T2` do not match. + * If `T1` or `T2` are the same this type will cause a compile-time error. + */ +type AssertTypesNotEqual extends false ? T1 : TMatchError, TMatchError = MatchError> = T1 & T2; + +export default AssertTypesNotEqual;