Open
Show file tree
Hide file tree
Changes from all commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Failed to load files.
Original file line numberDiff line numberDiff line change
Expand Up@@ -966,6 +966,47 @@ describe('emits', () => {
}
}
})

// should have `onXXX` props for emits
const a = defineComponent({
props: {
bar: String
},
emits: {
foo: (n: number) => n > 0
},
setup(props) {
expectType<((n: number) => boolean) | undefined>(props.onFoo)
}
})

const b = defineComponent({
extends: a,
props: {
bar2: String
},
emits: {
foo2: (n: number) => n > 0
},
setup(props) {
expectType<((n: number) => boolean) | undefined>(props.onFoo)
}
})

defineComponent({
mixins: [a, b],
props: {
bar3: String
},
emits: {
foo3: (n: number) => n > 0
},
setup(props) {
expectType<((n: number) => boolean) | undefined>(props.onFoo)
expectType<((n: number) => boolean) | undefined>(props.onFoo2)
expectType<((n: number) => boolean) | undefined>(props.onFoo3)
}
})
})

// describe('componentOptions setup should be `SetupContext`', () => {
Expand Down
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
import { Vue } from './vue'
import { VNode } from './vnode'
import { ComponentOptions as Vue2ComponentOptions } from './options'
import { EmitsOptions, SetupContext } from './v3-setup-context'
import { EmitsOptions, EmitsToProps, SetupContext } from './v3-setup-context'
import { Data, LooseRequired, UnionToIntersection } from './common'
import {
ComponentPropsOptions,
Expand DownExpand Up@@ -52,7 +52,7 @@ export type SetupFunction<
Emits extends EmitsOptions = {}
> = (
this: void,
props: Readonly<Props>,
props: Readonly<Props & EmitsToProps<Emits>>,
ctx: SetupContext<Emits>
) => RawBindings | (() => VNode | null) | void

Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -17,7 +17,7 @@ import {
CreateComponentPublicInstance
} from './v3-component-public-instance'
import { Data, HasDefined } from './common'
import { EmitsOptions } from './v3-setup-context'
import { EmitsOptions, EmitsToProps } from './v3-setup-context'
import { CreateElement, RenderContext } from './umd'

export type DefineComponent<
Expand All@@ -31,9 +31,9 @@ export type DefineComponent<
E extends EmitsOptions = {},
EE extends string = string,
Props = Readonly<
PropsOrPropOptions extends ComponentPropsOptions
(PropsOrPropOptions extends ComponentPropsOptions
? ExtractPropTypes<PropsOrPropOptions>
: PropsOrPropOptions
: PropsOrPropOptions) & EmitsToProps<E>
>,
Defaults = ExtractDefaultPropTypes<PropsOrPropOptions>
> = ComponentPublicInstanceConstructor<
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -13,6 +13,25 @@ export type ObjectEmitsOptions = Record<

export type EmitsOptions = ObjectEmitsOptions | string[]

export type EmitsToProps<T extends EmitsOptions> = T extends string[]
? {
[K in string & `on${Capitalize<T[number]>}`]?: (...args: any[]) => any
}
: T extends ObjectEmitsOptions
? {
[K in string &
`on${Capitalize<string & keyof T>}`]?: K extends `on${infer C}`
? T[Uncapitalize<C>] extends null
? (...args: any[]) => any
: (
...args: T[Uncapitalize<C>] extends (...args: infer P) => any
? P
: never
) => any
: never
}
: {}

export type EmitFn<
Options = ObjectEmitsOptions,
Event extends keyof Options = keyof Options,
Expand Down