feat(nuxt): add #fallback slot to server components types (#27097)

This commit is contained in:
Julien Huang 2024-05-08 14:33:54 +02:00 committed by GitHub
parent 6273f5d3b6
commit f687e211a8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 21 additions and 7 deletions

View File

@ -102,14 +102,20 @@ export const componentsTypeTemplate = {
filename: 'components.d.ts' as const, filename: 'components.d.ts' as const,
getContents: ({ app, nuxt }) => { getContents: ({ app, nuxt }) => {
const buildDir = nuxt.options.buildDir const buildDir = nuxt.options.buildDir
const componentTypes = app.components.filter(c => !c.island).map(c => [ const componentTypes = app.components.filter(c => !c.island).map((c) => {
c.pascalName, const type = `typeof ${genDynamicImport(isAbsolute(c.filePath)
`typeof ${genDynamicImport(isAbsolute(c.filePath)
? relative(buildDir, c.filePath).replace(/(?<=\w)\.(?!vue)\w+$/g, '') ? relative(buildDir, c.filePath).replace(/(?<=\w)\.(?!vue)\w+$/g, '')
: c.filePath.replace(/(?<=\w)\.(?!vue)\w+$/g, ''), { wrapper: false })}['${c.export}']`, : c.filePath.replace(/(?<=\w)\.(?!vue)\w+$/g, ''), { wrapper: false })}['${c.export}']`
]) return [
c.pascalName,
c.island || c.mode === 'server' ? `IslandComponent<${type}>` : type,
]
})
const islandType = 'type IslandComponent<T extends DefineComponent> = T & DefineComponent<{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, SlotsType<{ fallback: { error: unknown } }>>'
return ` return `
import type { DefineComponent, SlotsType } from 'vue'
${nuxt.options.experimental.componentIslands ? islandType : ''}
interface _GlobalComponents { interface _GlobalComponents {
${componentTypes.map(([pascalName, type]) => ` '${pascalName}': ${type}`).join('\n')} ${componentTypes.map(([pascalName, type]) => ` '${pascalName}': ${type}`).join('\n')}
${componentTypes.map(([pascalName, type]) => ` 'Lazy${pascalName}': ${type}`).join('\n')} ${componentTypes.map(([pascalName, type]) => ` 'Lazy${pascalName}': ${type}`).join('\n')}

View File

@ -0,0 +1,5 @@
<template>
<div>
Hello from server component !
</div>
</template>

View File

@ -1,5 +1,5 @@
import { describe, expectTypeOf, it } from 'vitest' import { describe, expectTypeOf, it } from 'vitest'
import type { Ref } from 'vue' import type { Ref, SlotsType } from 'vue'
import type { FetchError } from 'ofetch' import type { FetchError } from 'ofetch'
import type { NavigationFailure, RouteLocationNormalized, RouteLocationRaw, Router, useRouter as vueUseRouter } from '#vue-router' import type { NavigationFailure, RouteLocationNormalized, RouteLocationRaw, Router, useRouter as vueUseRouter } from '#vue-router'
@ -8,7 +8,7 @@ import { defineNuxtConfig } from 'nuxt/config'
import { callWithNuxt, isVue3 } from '#app' import { callWithNuxt, isVue3 } from '#app'
import type { NuxtError } from '#app' import type { NuxtError } from '#app'
import type { NavigateToOptions } from '#app/composables/router' import type { NavigateToOptions } from '#app/composables/router'
import { NuxtLayout, NuxtLink, NuxtPage, WithTypes } from '#components' import { NuxtLayout, NuxtLink, NuxtPage, ServerComponent, WithTypes } from '#components'
import { useRouter } from '#imports' import { useRouter } from '#imports'
interface TestResponse { message: string } interface TestResponse { message: string }
@ -372,6 +372,9 @@ describe('components', () => {
// TODO: assert typed slots, exposed, generics, etc. // TODO: assert typed slots, exposed, generics, etc.
}) })
it('include fallback slot in server components', () => {
expectTypeOf(ServerComponent.slots).toEqualTypeOf<SlotsType<{ fallback: { error: unknown } }> | undefined>()
})
}) })
describe('composables', () => { describe('composables', () => {