core-plugin-api: avoid symbol to identify RouteRefs at compile time

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
Patrik Oldsberg
2021-09-28 19:08:35 +02:00
parent 322b60d5f0
commit 98bd661240
6 changed files with 23 additions and 7 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/core-plugin-api': patch
---
Improve compatibility between different versions by defining the route reference type using a string key rather than a unique symbol. This change only applies to type checking and has no effect on the runtime value, where we still use the symbol.
+4 -4
View File
@@ -423,7 +423,7 @@ export type ExternalRouteRef<
Params extends AnyParams = any,
Optional extends boolean = any,
> = {
readonly [routeRefType]: 'external';
$$routeRefType: 'external';
params: ParamKeys<Params>;
optional?: Optional;
};
@@ -720,7 +720,7 @@ export type RoutePath = string;
//
// @public (undocumented)
export type RouteRef<Params extends AnyParams = any> = {
readonly [routeRefType]: 'absolute';
$$routeRefType: 'absolute';
params: ParamKeys<Params>;
path: string;
icon?: OldIconComponent;
@@ -811,7 +811,7 @@ export type StorageValueChange<T = any> = {
//
// @public (undocumented)
export type SubRouteRef<Params extends AnyParams = any> = {
readonly [routeRefType]: 'sub';
$$routeRefType: 'sub';
parent: RouteRef;
path: string;
params: ParamKeys<Params>;
@@ -901,6 +901,6 @@ export function withApis<T>(apis: TypesToApiRefs<T>): <P extends T>(
// src/apis/definitions/auth.d.ts:110:16 - (tsdoc-undefined-tag) The TSDoc tag "@IdentityApi" is not defined in this configuration
// src/apis/definitions/auth.d.ts:113:68 - (tsdoc-undefined-tag) The TSDoc tag "@AuthRequestOptions" is not defined in this configuration
// src/extensions/extensions.d.ts:14:5 - (ae-forgotten-export) The symbol "ComponentLoader" needs to be exported by the entry point index.d.ts
// src/routing/RouteRef.d.ts:34:5 - (ae-forgotten-export) The symbol "OldIconComponent" needs to be exported by the entry point index.d.ts
// src/routing/RouteRef.d.ts:35:5 - (ae-forgotten-export) The symbol "OldIconComponent" needs to be exported by the entry point index.d.ts
// src/routing/types.d.ts:30:5 - (ae-forgotten-export) The symbol "ParamKeys" needs to be exported by the entry point index.d.ts
```
@@ -27,6 +27,8 @@ export class ExternalRouteRefImpl<
Optional extends boolean,
> implements ExternalRouteRef<Params, Optional>
{
// The marker is used for type checking while the symbol is used at runtime.
declare $$routeRefType: 'external';
readonly [routeRefType] = 'external';
constructor(
@@ -34,6 +34,8 @@ export type RouteRefConfig<Params extends AnyParams> = {
export class RouteRefImpl<Params extends AnyParams>
implements RouteRef<Params>
{
// The marker is used for type checking while the symbol is used at runtime.
declare $$routeRefType: 'absolute';
readonly [routeRefType] = 'absolute';
constructor(
@@ -29,6 +29,8 @@ const PARAM_PATTERN = /^\w+$/;
export class SubRouteRefImpl<Params extends AnyParams>
implements SubRouteRef<Params>
{
// The marker is used for type checking while the symbol is used at runtime.
declare $$routeRefType: 'sub';
readonly [routeRefType] = 'sub';
constructor(
@@ -33,13 +33,18 @@ export type RouteFunc<Params extends AnyParams> = (
...[params]: Params extends undefined ? readonly [] : readonly [Params]
) => string;
// This symbol is what we use at runtime to determine whether a given object
// is a type of RouteRef or not. It doesn't work well in TypeScript though since
// the `unique symbol` will refer to different values between package versions.
// For that reason we use the marker $$routeRefType to represent the symbol at
// compile-time instead of using the symbol directly.
export const routeRefType: unique symbol = getOrCreateGlobalSingleton<any>(
'route-ref-type',
() => Symbol('route-ref-type'),
);
export type RouteRef<Params extends AnyParams = any> = {
readonly [routeRefType]: 'absolute';
$$routeRefType: 'absolute'; // See routeRefType above
params: ParamKeys<Params>;
@@ -53,7 +58,7 @@ export type RouteRef<Params extends AnyParams = any> = {
};
export type SubRouteRef<Params extends AnyParams = any> = {
readonly [routeRefType]: 'sub';
$$routeRefType: 'sub'; // See routeRefType above
parent: RouteRef;
@@ -66,7 +71,7 @@ export type ExternalRouteRef<
Params extends AnyParams = any,
Optional extends boolean = any,
> = {
readonly [routeRefType]: 'external';
$$routeRefType: 'external'; // See routeRefType above
params: ParamKeys<Params>;