types(runtime-core): provide valid type for default $emit (#1498)

This commit is contained in:
Carlos Rodrigues 2020-07-08 16:51:03 +01:00 committed by GitHub
parent f0394e2a61
commit 1e90605c15
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 28 additions and 11 deletions

View File

@ -79,7 +79,7 @@ export interface ComponentInternalOptions {
export interface FunctionalComponent<
P = {},
E extends EmitsOptions = Record<string, any>
E extends EmitsOptions = {}
> extends ComponentInternalOptions {
// use of any here is intentional so it can be a valid JSX Element constructor
(props: P, ctx: SetupContext<E>): any

View File

@ -25,6 +25,8 @@ export type EmitFn<
Event extends keyof Options = keyof Options
> = Options extends any[]
? (event: Options[0], ...args: any[]) => void
: {} extends Options // if the emit is empty object (usually the default value for emit) should be converted to function
? (event: string, ...args: any[]) => void
: UnionToIntersection<
{
[key in Event]: Options[key] extends ((...args: infer Args) => any)

View File

@ -12,6 +12,7 @@ import { isObject, isArray } from '@vue/shared'
import { RawSlots } from './componentSlots'
import { FunctionalComponent, Component } from './component'
import { ComponentOptions } from './componentOptions'
import { EmitsOptions } from './componentEmits'
// `h` is a more user-friendly version of `createVNode` that allows omitting the
// props when possible. It is intended for manually written render functions.
@ -107,8 +108,8 @@ export function h(
): VNode
// functional component
export function h<P>(
type: FunctionalComponent<P>,
export function h<P, E extends EmitsOptions = {}>(
type: FunctionalComponent<P, E>,
props?: (RawProps & P) | ({} extends P ? null : never),
children?: RawChildren | RawSlots
): VNode

View File

@ -6,7 +6,8 @@ import {
reactive,
createApp,
expectError,
expectType
expectType,
ComponentPublicInstance
} from './index'
describe('with object props', () => {
@ -669,4 +670,17 @@ describe('emits', () => {
expectError(this.$emit('nope'))
}
})
// without emits
defineComponent({
setup(props, { emit }) {
emit('test', 1)
emit('test')
}
})
// emit should be valid when ComponentPublicInstance is used.
const instance = {} as ComponentPublicInstance
instance.$emit('test', 1)
instance.$emit('test')
})