App,
VNode,
shallowRef,
+ ComponentOptions,
} from 'vue'
import { compile } from '@vue/compiler-dom'
import * as runtimeDom from '@vue/runtime-dom'
export interface MountOptions {
propsData: Record<string, any>
provide: Record<string | symbol, any>
- components: Record<string, Component>
+ components: ComponentOptions['components']
slots: Record<string, string>
}
computed,
reactive,
unref,
- Component,
+ VNodeProps,
} from 'vue'
import { RouteLocationRaw, VueUseOptions, RouteLocation } from './types'
import { isSameLocationObject, isSameRouteRecord } from './location'
import { routerKey, routeLocationKey } from './injectionSymbols'
import { RouteRecord } from './matcher/types'
-interface LinkProps {
+export interface RouterLinkProps {
to: RouteLocationRaw
- // TODO: refactor using extra options allowed in router.push
+ // TODO: refactor using extra options allowed in router.push. Needs RFC
replace?: boolean
}
-type UseLinkOptions = VueUseOptions<LinkProps>
+type UseLinkOptions = VueUseOptions<RouterLinkProps>
// TODO: we could allow currentRoute as a prop to expose `isActive` and
// `isExactActive` behavior should go through an RFC
}
}
-export const RouterLink = (defineComponent({
+export const RouterLinkImpl = defineComponent({
name: 'RouterLink',
props: {
to: {
)
}
},
-}) as unknown) as Component
+})
+
+// export the public type for h/tsx inference
+// also to avoid inline import() in generated d.ts files
+export const RouterLink = (RouterLinkImpl as any) as {
+ new (): {
+ $props: VNodeProps & RouterLinkProps
+ }
+}
function guardEvent(e: MouseEvent) {
// don't redirect with control keys
computed,
ref,
ComponentPublicInstance,
- Component,
+ VNodeProps,
} from 'vue'
-import { RouteLocationNormalizedLoaded } from './types'
+import { RouteLocationNormalizedLoaded, RouteLocationNormalized } from './types'
import {
matchedRouteKey,
viewDepthKey,
routeLocationKey,
} from './injectionSymbols'
-export const RouterView = (defineComponent({
+export interface RouterViewProps {
+ name?: string
+ // allow looser type for user facing api
+ route?: RouteLocationNormalized
+}
+
+export const RouterViewImpl = defineComponent({
name: 'RouterView',
props: {
name: {
: null
}
},
-}) as unknown) as Component
+})
+
+// export the public type for h/tsx inference
+// also to avoid inline import() in generated d.ts files
+export const RouterView = (RouterViewImpl as any) as {
+ new (): {
+ $props: VNodeProps & RouterViewProps
+ }
+}
export { NavigationFailureType, NavigationFailure } from './errors'
export { onBeforeRouteLeave, onBeforeRouteUpdate } from './navigationGuards'
-export { RouterLink, useLink } from './RouterLink'
-export { RouterView } from './RouterView'
+export { RouterLink, useLink, RouterLinkProps } from './RouterLink'
+export { RouterView, RouterViewProps } from './RouterView'
export * from './useApi'
--- /dev/null
+import { expectError, expectType } from 'tsd'
+import {
+ RouterLink,
+ RouterView,
+ createRouter,
+ createMemoryHistory,
+} from './index'
+
+let router = createRouter({
+ history: createMemoryHistory(),
+ routes: [],
+})
+
+// RouterLink
+expectError(<RouterLink />)
+expectType<JSX.Element>(<RouterLink to="/foo" replace />)
+expectType<JSX.Element>(<RouterLink to="/foo" />)
+expectType<JSX.Element>(<RouterLink to={{ path: '/foo' }} />)
+
+// RouterView
+expectType<JSX.Element>(<RouterView />)
+expectType<JSX.Element>(<RouterView name="foo" />)
+expectType<JSX.Element>(<RouterView route={router.currentRoute.value} />)