From: Eduardo San Martin Morote Date: Tue, 5 Jul 2022 07:57:52 +0000 (+0200) Subject: fix(types): allow simpler type check of route records (#1453) X-Git-Tag: v4.1.1~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e3078a4190c799ec4f01fa5c46d64c54c0e95034;p=thirdparty%2Fvuejs%2Frouter.git fix(types): allow simpler type check of route records (#1453) Fix #1452 --- diff --git a/packages/router/__tests__/matcher/resolve.spec.ts b/packages/router/__tests__/matcher/resolve.spec.ts index 3e13f666..672e79bb 100644 --- a/packages/router/__tests__/matcher/resolve.spec.ts +++ b/packages/router/__tests__/matcher/resolve.spec.ts @@ -42,11 +42,9 @@ describe('RouterMatcher.resolve', () => { throw new Error('not handled') } else { // use one single record - // @ts-expect-error: One way or the other it false if (!resolved.matched) resolved.matched = record.map(normalizeRouteRecord) // allow passing an expect.any(Array) else if (Array.isArray(resolved.matched)) - // @ts-expect-error: same as above resolved.matched = resolved.matched.map(m => ({ ...normalizeRouteRecord(m as any), aliasOf: m.aliasOf, diff --git a/packages/router/src/matcher/index.ts b/packages/router/src/matcher/index.ts index e6d2ceac..eda41a87 100644 --- a/packages/router/src/matcher/index.ts +++ b/packages/router/src/matcher/index.ts @@ -159,7 +159,7 @@ export function createRouterMatcher( removeRoute(record.name) } - if ('children' in mainNormalizedRecord) { + if (mainNormalizedRecord.children) { const children = mainNormalizedRecord.children for (let i = 0; i < children.length; i++) { addRoute( @@ -353,7 +353,6 @@ export function normalizeRouteRecord( aliasOf: undefined, beforeEnter: record.beforeEnter, props: normalizeRecordProps(record), - // @ts-expect-error: record.children only exists in some cases children: record.children || [], instances: {}, leaveGuards: new Set(), diff --git a/packages/router/src/matcher/types.ts b/packages/router/src/matcher/types.ts index f48c7522..a4288610 100644 --- a/packages/router/src/matcher/types.ts +++ b/packages/router/src/matcher/types.ts @@ -4,7 +4,7 @@ import { _RouteRecordBase, _RouteRecordProps, NavigationGuardNextCallback, - RouteRecordSingleViewWithChildren, + RouteRecordRaw, } from '../types' import { ComponentPublicInstance } from 'vue' @@ -32,7 +32,7 @@ export interface RouteRecordNormalized { /** * Nested route records. */ - children: RouteRecordSingleViewWithChildren['children'] + children: RouteRecordRaw[] /** * {@inheritDoc _RouteRecordBase.meta} */ diff --git a/packages/router/src/types/index.ts b/packages/router/src/types/index.ts index b13e936d..865d510f 100644 --- a/packages/router/src/types/index.ts +++ b/packages/router/src/types/index.ts @@ -262,6 +262,11 @@ export interface _RouteRecordBase extends PathParserOptions { * Arbitrary data attached to the record. */ meta?: RouteMeta + + /** + * Array of nested routes. + */ + children?: RouteRecordRaw[] } /** @@ -298,6 +303,9 @@ export interface RouteRecordSingleView extends _RouteRecordBase { */ component: RawRouteComponent components?: never + children?: never + redirect?: never + /** * Allow passing down params as props to the component rendered by `router-view`. */ @@ -314,9 +322,6 @@ export interface RouteRecordSingleViewWithChildren extends _RouteRecordBase { component?: RawRouteComponent | null | undefined components?: never - /** - * Array of nested routes. - */ children: RouteRecordRaw[] /** @@ -334,6 +339,8 @@ export interface RouteRecordMultipleViews extends _RouteRecordBase { */ components: Record component?: never + children?: never + redirect?: never /** * Allow passing down params as props to the component rendered by @@ -352,6 +359,7 @@ export interface RouteRecordMultipleViewsWithChildren extends _RouteRecordBase { */ components?: Record | null | undefined component?: never + redirect?: never children: RouteRecordRaw[] diff --git a/packages/router/test-dts/perfNamedRoutes.test-d.ts b/packages/router/test-dts/perfNamedRoutes.test-d.ts deleted file mode 100644 index 4b841f56..00000000 --- a/packages/router/test-dts/perfNamedRoutes.test-d.ts +++ /dev/null @@ -1,182 +0,0 @@ -import { createRouter, createMemoryHistory } from '.' -import { defineComponent } from 'vue' - -const Home = defineComponent({}) -const User = defineComponent({}) -const LongView = defineComponent({}) -const component = defineComponent({}) - -const router = createRouter({ - history: createMemoryHistory(), - routes: [ - { path: '/home', redirect: '/' }, - { - path: '/', - components: { default: Home, other: component }, - }, - { - path: '/always-redirect', - component, - }, - { path: '/users/:id', name: 'user', component: User, props: true }, - { path: '/documents/:id', name: 'docs', component: User, props: true }, - { path: '/optional/:id?', name: 'optional', component: User, props: true }, - // { path: encodeURI('/n/€'), name: 'euro', component }, - { path: '/n/:n', name: 'increment', component }, - { path: '/multiple/:a/:b', name: 'multiple', component }, - { path: '/long-:n', name: 'long', component: LongView }, - { - path: '/lazy', - component, - }, - { - path: '/with-guard/:n', - name: 'guarded', - component, - }, - { path: '/cant-leave', component }, - { - path: '/children', - name: 'WithChildren', - component, - children: [ - { path: '', alias: 'alias', name: 'default-child', component }, - { path: 'a', name: 'a-child', component }, - { - path: 'b', - name: 'WithChildrenB', - component, - children: [ - { - path: '', - name: 'b-child', - component, - }, - { path: 'a2', component }, - { path: 'b2', component }, - ], - }, - ], - }, - { path: '/with-data', component, name: 'WithData' }, - { path: '/rep/:a*', component, name: 'repeat' }, - { path: '/:data(.*)' as '/:data', component, name: 'NotFound' }, - { - path: '/nested', - alias: '/anidado', - component, - name: 'Nested', - children: [ - { - path: 'nested', - alias: 'a', - name: 'NestedNested', - component, - children: [ - { - name: 'NestedNestedNested', - path: 'nested', - component, - }, - ], - }, - { - path: 'other', - alias: 'otherAlias', - component, - name: 'NestedOther', - }, - { - path: 'also-as-absolute', - alias: '/absolute', - name: 'absolute-child', - component, - }, - ], - }, - - { - path: '/parent/:id', - name: 'parent', - component, - props: true, - alias: '/p/:id', - children: [ - // empty child - { path: '', name: 'child-id', component }, - // child with absolute path. we need to add an `id` because the parent needs it - { path: '/p_:id/absolute-a', alias: 'as-absolute-a', component }, - // same as above but the alias is absolute - { path: 'as-absolute-b', alias: '/p_:id/absolute-b', component }, - ], - }, - { - path: '/dynamic', - name: 'dynamic', - component, - end: false, - strict: true, - }, - - { - path: '/admin', - children: [ - { path: '', component }, - { path: 'dashboard', component }, - { path: 'settings', component }, - ], - }, - ] as const, -}) - -router.resolve('/hello') - -router.push('/admin') -router.push('/admin2') -router.push('/adminaoeu') -router.push('/admin/settings') -router.push('/admin') -router.push('/admin') -router.push('/children') -router.push('/admin') -router.push('/admin') -router.push('/admin') -router.push('/admin?[{}') -router.push('/admin') -router.push('/admin') -router.push('/admin') -router.push('/admin') -router.push('/admin') -router.push('/admin') -router.push('/admin') - -// router.pushNamed({name: ''}) -// router.pushNamed({ name: 'Nested' }) - -export type LiteralUnion = - | LiteralType - | (BaseType & Record) - -// function pushStr( -// route: LiteralUnion> -// ) {} -// pushStr('/admin/dashboard') - -// function push1( -// route: RouteNamedMap[keyof RouteNamedMap] -// ) {} -// push1({ }) - -// function pushEnd(route: keyof RouteNamedMap) {} - -// pushEnd('NotFound') - -// function push( -// route: -// | LiteralUnion> -// | { -// name: keyof RouteNamedMap -// } -// ) {} - -// push('/documents/:id') diff --git a/packages/router/test-dts/routeRecords.test-d.ts b/packages/router/test-dts/routeRecords.test-d.ts index bcc59d9b..e806dad1 100644 --- a/packages/router/test-dts/routeRecords.test-d.ts +++ b/packages/router/test-dts/routeRecords.test-d.ts @@ -11,10 +11,29 @@ routes.push({ path: '/', redirect: '/foo' }) // @ts-expect-error cannot have components and component at the same time routes.push({ path: '/', components, component }) +// a redirect record with children to point to a child routes.push({ path: '/', redirect: '/foo', - children: [], + children: [ + { + path: 'foo', + component, + }, + ], +}) + +// same but with a nested route +routes.push({ + path: '/', + component, + redirect: '/foo', + children: [ + { + path: 'foo', + component, + }, + ], }) routes.push({ path: '/', component, props: true }) @@ -29,3 +48,14 @@ routes.push({ path: '/', components, props: true }) // component, // components, // } + +export function filterNestedChildren(children: RouteRecordRaw[]) { + return children.filter(r => { + if (r.redirect) { + r.children?.map(() => {}) + } + if (r.children) { + r.children = filterNestedChildren(r.children) + } + }) +}