mirror of
https://github.com/nuxt/nuxt.git
synced 2025-02-11 11:18:06 +00:00
fix(nuxt): ensure <NuxtLayout>
fallback
prop is typed (#30832)
This commit is contained in:
parent
34a731d00e
commit
d9ba0d2249
@ -1,4 +1,4 @@
|
|||||||
import type { DefineComponent, MaybeRef, VNode } from 'vue'
|
import type { DefineComponent, ExtractPublicPropTypes, MaybeRef, PropType, VNode } from 'vue'
|
||||||
import { Suspense, computed, defineComponent, h, inject, mergeProps, nextTick, onMounted, provide, ref, unref } from 'vue'
|
import { Suspense, computed, defineComponent, h, inject, mergeProps, nextTick, onMounted, provide, ref, unref } from 'vue'
|
||||||
import type { RouteLocationNormalizedLoaded } from 'vue-router'
|
import type { RouteLocationNormalizedLoaded } from 'vue-router'
|
||||||
|
|
||||||
@ -30,19 +30,23 @@ const LayoutLoader = defineComponent({
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
export default defineComponent({
|
// props are moved outside of defineComponent to later explicitly assert the prop types
|
||||||
name: 'NuxtLayout',
|
// this avoids type loss/simplification resulting in things like MaybeRef<string | false>, keeping type hints for layout names
|
||||||
inheritAttrs: false,
|
const nuxtLayoutProps = {
|
||||||
props: {
|
|
||||||
name: {
|
name: {
|
||||||
type: [String, Boolean, Object] as unknown as () => unknown extends PageMeta['layout'] ? MaybeRef<string | false> : PageMeta['layout'],
|
type: [String, Boolean, Object] as PropType<unknown extends PageMeta['layout'] ? MaybeRef<string | false> : PageMeta['layout']>,
|
||||||
default: null,
|
default: null,
|
||||||
},
|
},
|
||||||
fallback: {
|
fallback: {
|
||||||
type: [String, Object] as unknown as () => unknown extends PageMeta['layout'] ? MaybeRef<string> : PageMeta['layout'],
|
type: [String, Object] as PropType<unknown extends PageMeta['layout'] ? MaybeRef<string> : PageMeta['layout']>,
|
||||||
default: null,
|
default: null,
|
||||||
},
|
},
|
||||||
},
|
}
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: 'NuxtLayout',
|
||||||
|
inheritAttrs: false,
|
||||||
|
props: nuxtLayoutProps,
|
||||||
setup (props, context) {
|
setup (props, context) {
|
||||||
const nuxtApp = useNuxtApp()
|
const nuxtApp = useNuxtApp()
|
||||||
// Need to ensure (if we are not a child of `<NuxtPage>`) that we use synchronous route (not deferred)
|
// Need to ensure (if we are not a child of `<NuxtPage>`) that we use synchronous route (not deferred)
|
||||||
@ -95,9 +99,7 @@ export default defineComponent({
|
|||||||
}).default()
|
}).default()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}) as unknown as DefineComponent<{
|
}) as DefineComponent<ExtractPublicPropTypes<typeof nuxtLayoutProps>>
|
||||||
name?: (unknown extends PageMeta['layout'] ? MaybeRef<string | false> : PageMeta['layout']) | undefined
|
|
||||||
}>
|
|
||||||
|
|
||||||
const LayoutProvider = defineComponent({
|
const LayoutProvider = defineComponent({
|
||||||
name: 'NuxtLayoutProvider',
|
name: 'NuxtLayoutProvider',
|
||||||
|
9
test/fixtures/basic-types/types.ts
vendored
9
test/fixtures/basic-types/types.ts
vendored
@ -258,7 +258,7 @@ describe('typed router integration', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
describe('layouts', () => {
|
describe('layouts', () => {
|
||||||
it('recognizes named layouts', () => {
|
it('definePageMeta recognizes named layouts', () => {
|
||||||
definePageMeta({ layout: 'custom' })
|
definePageMeta({ layout: 'custom' })
|
||||||
definePageMeta({ layout: 'pascal-case' })
|
definePageMeta({ layout: 'pascal-case' })
|
||||||
definePageMeta({ layout: 'override' })
|
definePageMeta({ layout: 'override' })
|
||||||
@ -266,11 +266,14 @@ describe('layouts', () => {
|
|||||||
definePageMeta({ layout: 'invalid-layout' })
|
definePageMeta({ layout: 'invalid-layout' })
|
||||||
})
|
})
|
||||||
|
|
||||||
it('allows typing layouts', () => {
|
it('NuxtLayout recognizes named layouts', () => {
|
||||||
h(NuxtLayout, { name: 'custom' })
|
h(NuxtLayout, { name: 'custom' })
|
||||||
|
|
||||||
// @ts-expect-error Invalid layout
|
// @ts-expect-error Invalid layout
|
||||||
h(NuxtLayout, { name: 'invalid-layout' })
|
h(NuxtLayout, { name: 'invalid-layout' })
|
||||||
|
|
||||||
|
h(NuxtLayout, { fallback: 'custom' })
|
||||||
|
// @ts-expect-error Invalid layout
|
||||||
|
h(NuxtLayout, { fallback: 'invalid-layout' })
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user