Skip to content

Commit

Permalink
fix: functional component & public instance
Browse files Browse the repository at this point in the history
  • Loading branch information
sxzz committed Mar 30, 2023
1 parent 2b70d7f commit a655521
Show file tree
Hide file tree
Showing 7 changed files with 45 additions and 23 deletions.
8 changes: 8 additions & 0 deletions packages/compiler-sfc/src/compileScript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -726,6 +726,7 @@ export function compileScript(
let propsOption = undefined
let emitsOption = undefined
let exposeOption = undefined
let slotsOption = undefined
if (optionsRuntimeDecl.type === 'ObjectExpression') {
for (const prop of optionsRuntimeDecl.properties) {
if (
Expand All @@ -735,6 +736,7 @@ export function compileScript(
if (prop.key.name === 'props') propsOption = prop
if (prop.key.name === 'emits') emitsOption = prop
if (prop.key.name === 'expose') exposeOption = prop
if (prop.key.name === 'slots') slotsOption = prop
}
}
}
Expand All @@ -757,6 +759,12 @@ export function compileScript(
exposeOption
)
}
if (slotsOption) {
error(
`${DEFINE_OPTIONS}() cannot be used to declare slots. Use ${DEFINE_SLOTS}() instead.`,
slotsOption
)
}

return true
}
Expand Down
11 changes: 10 additions & 1 deletion packages/dts-test/functionalComponent.test-d.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { h, Text, FunctionalComponent, Component } from 'vue'
import { h, Text, FunctionalComponent, Component, SlotsType, VNode } from 'vue'
import { expectType } from './utils'

// simple function signature
Expand Down Expand Up @@ -68,3 +68,12 @@ const Qux: FunctionalComponent<{}, ['foo', 'bar']> = (props, { emit }) => {
}

expectType<Component>(Qux)

const Quux: FunctionalComponent<{}, {}, { default: [foo: number] }> = (
props,
{ emit, slots }
) => {
expectType<{ default: (foo: number) => VNode[] }>(slots)
}
expectType<Component>(Quux)
;<Quux />
10 changes: 3 additions & 7 deletions packages/runtime-core/src/apiSetupHelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,9 +156,7 @@ export function defineOptions<
C extends ComputedOptions = {},
M extends MethodOptions = {},
Mixin extends ComponentOptionsMixin = ComponentOptionsMixin,
Extends extends ComponentOptionsMixin = ComponentOptionsMixin,
E extends EmitsOptions = EmitsOptions,
EE extends string = string
Extends extends ComponentOptionsMixin = ComponentOptionsMixin
>(
options?: ComponentOptionsWithoutProps<
{},
Expand All @@ -167,10 +165,8 @@ export function defineOptions<
C,
M,
Mixin,
Extends,
E,
EE
> & { emits?: undefined; expose?: undefined }
Extends
> & { emits?: undefined; expose?: undefined; slots?: undefined }
): void {
if (__DEV__) {
warnRuntimeUsage(`defineOptions`)
Expand Down
10 changes: 5 additions & 5 deletions packages/runtime-core/src/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ import {
normalizePropsOptions
} from './componentProps'
import {
Slots,
initSlots,
InternalSlots,
SlotsType,
Expand Down Expand Up @@ -126,12 +125,13 @@ export interface ComponentInternalOptions {
export interface FunctionalComponent<
P = {},
E extends EmitsOptions = {},
S extends SlotsType = {}
S extends Record<string, any[]> = {}
> extends ComponentInternalOptions {
// use of any here is intentional so it can be a valid JSX Element constructor
(props: P, ctx: Omit<SetupContext<E, S>, 'expose'>): any
(props: P, ctx: Omit<SetupContext<E, SlotsType<S>>, 'expose'>): any
props?: ComponentPropsOptions<P>
emits?: E | (keyof E)[]
slots?: SlotsType<S>
inheritAttrs?: boolean
displayName?: string
compatConfig?: CompatConfig
Expand All @@ -156,7 +156,7 @@ export type ConcreteComponent<
M extends MethodOptions = MethodOptions
> =
| ComponentOptions<Props, RawBindings, D, C, M>
| FunctionalComponent<Props, any>
| FunctionalComponent<Props, any, any>

/**
* A type used in public APIs where a component type is expected.
Expand All @@ -183,7 +183,7 @@ export type SetupContext<
> = E extends any
? {
attrs: Data
slots: [keyof S] extends [never] ? Slots : TypedSlots<S>
slots: TypedSlots<S>
emit: EmitFn<E>
expose: (exposed?: Record<string, any>) => void
}
Expand Down
6 changes: 4 additions & 2 deletions packages/runtime-core/src/componentPublicInstance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ import {
ComponentInjectOptions
} from './componentOptions'
import { EmitsOptions, EmitFn } from './componentEmits'
import { Slots, SlotsType } from './componentSlots'
import { SlotsType, TypedSlots } from './componentSlots'
import { markAttrsAccessed } from './componentRenderUtils'
import { currentRenderingInstance } from './componentRenderContext'
import { warn } from './warning'
Expand Down Expand Up @@ -164,6 +164,7 @@ export type CreateComponentPublicInstance<
PublicC,
PublicM,
E,
S,
PublicProps,
PublicDefaults,
MakeDefaultsOptional,
Expand All @@ -180,6 +181,7 @@ export type ComponentPublicInstance<
C extends ComputedOptions = {},
M extends MethodOptions = {},
E extends EmitsOptions = {},
S extends SlotsType = {},
PublicProps = P,
Defaults = {},
MakeDefaultsOptional extends boolean = false,
Expand All @@ -195,7 +197,7 @@ export type ComponentPublicInstance<
>
$attrs: Data
$refs: Data
$slots: Slots
$slots: TypedSlots<S>
$root: ComponentPublicInstance | null
$parent: ComponentPublicInstance | null
$emit: EmitFn<E>
Expand Down
15 changes: 9 additions & 6 deletions packages/runtime-core/src/componentSlots.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,16 @@ export type SlotsType<T extends Record<string, any[]> = Record<string, any[]>> =
{
[SlotSymbol]?: T
}
export type TypedSlots<S extends SlotsType> = Readonly<
Prettify<{
[K in keyof NonNullable<S[typeof SlotSymbol]>]: Slot<
NonNullable<S[typeof SlotSymbol]>[K]

export type TypedSlots<S extends SlotsType> = [keyof S] extends [never]
? Slots
: Readonly<
Prettify<{
[K in keyof NonNullable<S[typeof SlotSymbol]>]: Slot<
NonNullable<S[typeof SlotSymbol]>[K]
>
}>
>
}>
>

export type RawSlots = {
[name: string]: unknown
Expand Down
8 changes: 6 additions & 2 deletions packages/runtime-core/src/h.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,12 @@ export function h(
): VNode

// functional component
export function h<P, E extends EmitsOptions = {}>(
type: FunctionalComponent<P, E>,
export function h<
P,
E extends EmitsOptions = {},
S extends Record<string, any[]> = {}
>(
type: FunctionalComponent<P, E, S>,
props?: (RawProps & P) | ({} extends P ? null : never),
children?: RawChildren | RawSlots
): VNode
Expand Down

0 comments on commit a655521

Please sign in to comment.