Skip to content

types(defineComponent): DefineComponent refactor #4465

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
75e447e
feat(types): string type inferrences
pikax Sep 19, 2020
55c6c2c
chore: add h defineComponent
pikax Sep 19, 2020
b99a543
chore: v-model emit update:${props}
pikax Sep 19, 2020
83e9abd
types(defineComponent): Support emit when using functionalComponent
pikax Oct 27, 2020
e0a1656
types(slots): Add typed slots
pikax Nov 30, 2020
b4dc05f
chore: fix tests
pikax Nov 30, 2020
8809f5b
Merge branch 'master-upstream' into types/string_type_inference
pikax Dec 19, 2020
3cb7f02
chore: rename `capitalize` to Capitalize<T>
pikax Dec 19, 2020
341b350
chore: rollback package and typescript dep
pikax Dec 19, 2020
8089a6a
chore: fix build
pikax Dec 19, 2020
415460a
chore: trying to fix tests
pikax Dec 19, 2020
f24b161
chore: defineComponent working as expected with `h`
pikax Dec 19, 2020
8e07103
chore: kinda working but not really
pikax Dec 19, 2020
47de099
chore: ...
pikax Dec 19, 2020
eb87718
Merge branch 'master-upstream' into types/string_type_inference
pikax Jan 26, 2021
748550c
chore: fix test
pikax Jan 26, 2021
e2cac07
types(defineComponent): support for expose component types
pikax Mar 9, 2021
3ccdc0b
chore: add directive typing test
pikax Mar 9, 2021
e140b07
chore: exposed type suppor
pikax Mar 9, 2021
5f49e9c
chore: add global directive type
pikax Mar 9, 2021
fbb62bc
chore: fix tests
pikax Mar 9, 2021
b10bc77
chore: clean dup code
pikax Mar 10, 2021
d0b13fa
chore: add GlobalComponents and GlobalDirectives
pikax Mar 11, 2021
057bad9
chore: add Suspense, KeepAlive, Teleport to GlobalComponents
pikax Mar 13, 2021
9970b45
chore: add Transition and TransitionGroup to globalComponents
pikax Mar 13, 2021
2498929
chore: add BaseTransition ass globalComponent
pikax Mar 13, 2021
b792c6c
chore: add VShow as a globalDirective
pikax Mar 13, 2021
980dbf3
chore: add BaseTransition
pikax Mar 13, 2021
53379a1
Merge branch 'upstream' into feat/typed_slots
pikax Mar 13, 2021
d729fba
chore: added support for `h`
pikax Mar 13, 2021
200838d
chore: correct interface with file name
pikax Mar 14, 2021
dffd7c9
Merge branch 'master' into types/refactor_defineComponent
pikax Mar 30, 2021
08c1217
chore: wrap component to get the type
pikax Mar 30, 2021
ca63ffa
chore: typed directives + VModel directive
pikax Apr 15, 2021
16352ca
chore: move arg after modifiers and add tests
pikax Apr 18, 2021
7754d7e
chore: improve tests
pikax Apr 18, 2021
6558afd
chore: add vOn directive as global
pikax Apr 23, 2021
99741b8
chore: vmodel WIP
pikax Apr 25, 2021
a54a692
Merge branch 'master-upstream' into types/string_type_inference
pikax Jul 16, 2021
0cf01a5
minor: fix test
pikax Jul 16, 2021
675a642
Merge branch 'master-upstream' into types/refactor_defineComponent
pikax Aug 15, 2021
5573d90
chore: remove bad import and fix compat render type
pikax Aug 15, 2021
a3408d7
chore: remove type
pikax Aug 15, 2021
7583477
chore: improve test
pikax Aug 15, 2021
5300104
chore: Merge branch 'master-upstream' into feat/typed_slots
pikax Aug 20, 2021
8a73d1e
chore: Merge branch 'feat/typed_slots' into types/Merge_DefineCompone…
pikax Aug 20, 2021
6fe8330
chore: Merge branch 'types/string_type_inference' into types/Merge_De…
pikax Aug 28, 2021
b3d2b05
chore: Merge branch 'types/definecomponent_functional_emit' into type…
pikax Aug 28, 2021
18a78af
chore: Merge branch 'types/refactor_defineComponent' into types/Merge…
pikax Aug 28, 2021
372eeb2
wip: not properly working
pikax Aug 28, 2021
847d67d
wip: improve mixin emits
pikax Aug 28, 2021
1c4ddad
chore: duplicated must Component types
pikax Aug 29, 2021
e201d2f
chore: defineComponent changes
pikax Aug 29, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
chore: kinda working but not really
  • Loading branch information
pikax committed Dec 19, 2020
commit 8e071039c8565eb5888d42a3cea203ec1a5e544b
150 changes: 77 additions & 73 deletions packages/runtime-core/src/h.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,10 @@ import { RawSlots } from './componentSlots'
import {
FunctionalComponent,
Component,
ComponentOptions,
ConcreteComponent
} from './component'
import { EmitFn, EmitsOptions } from './componentEmits'
import { EmitsOptions } from './componentEmits'
import { DefineComponent } from './apiDefineComponent'
import { ExtractDefaultPropTypes, ExtractPropTypes, InferPropType } from './componentProps'

// `h` is a more user-friendly version of `createVNode` that allows omitting the
// props when possible. It is intended for manually written render functions.
Expand Down Expand Up @@ -90,13 +88,14 @@ type ExtractEmitEvents<T> =
: (...args: any[]) => void
}


type ExtractEmitPropUpdate<P = {}> =
type ExtractEmitPropUpdate<P = {}, PK extends keyof P & string = keyof P & string> =
(P extends Readonly<Array<infer V>>
? ({ [K in V & string as `onUpdate:${K}`]?: (value: any) => void })
: P extends any[]
? ({ [K in P & string as `onUpdate:${K}`]?: (value: any) => void })
: { [K in keyof P & string as `onUpdate:${K}`]?: (value: P[K]) => void }
:
// we need to omit if it infers emit as props
{ [K in keyof Omit<P, `on${Capitalize<PK>}`> & string as `onUpdate:${K}`]?: (value: P[K]) => void }
)

type RenderProps<P, E extends EmitsOptions = {}> =
Expand All @@ -105,64 +104,70 @@ type RenderProps<P, E extends EmitsOptions = {}> =
// The following is a series of overloads for providing props validation of
// manually written render functions.

// // element
// export function h(type: string, children?: RawChildren): VNode
// export function h(
// type: string,
// props?: RawProps | null,
// children?: RawChildren | RawSlots
// ): VNode

// // fragment
// export function h(type: typeof Fragment, children?: VNodeArrayChildren): VNode
// export function h(
// type: typeof Fragment,
// props?: RawProps | null,
// children?: VNodeArrayChildren
// ): VNode

// // teleport (target prop is required)
// export function h(
// type: typeof Teleport,
// props: RawProps & TeleportProps,
// children: RawChildren
// ): VNode

// // suspense
// export function h(type: typeof Suspense, children?: RawChildren): VNode
// export function h(
// type: typeof Suspense,
// props?: (RawProps & SuspenseProps) | null,
// children?: RawChildren | RawSlots
// ): VNode

// // functional component
// export function h<P, E extends EmitsOptions = {}>(
// type: FunctionalComponent<P, E>,
// props?: (RawProps & P & Partial<ExtractEmitEvents<E>>) | ({} extends P ? null : never),
// children?: RawChildren | RawSlots
// ): VNode

// // catch-all for generic component types
// export function h(type: Component, children?: RawChildren): VNode

// // concrete component
// export function h<P>(
// type: ConcreteComponent | string,
// children?: RawChildren
// ): VNode
// export function h<P, E extends EmitsOptions = {}>(
// type: ConcreteComponent<P, any, any, any, any, any, any, E> | string,
// props?: (RawProps & P & ExtractEmitEvents<E>) | ({} extends P ? null : never),
// children?: RawChildren
// ): VNode

// // component without props
// export function h(
// type: Component,
// props: null,
// children?: RawChildren | RawSlots
// ): VNode
// functional component
// NOTE: is set on top to allow infer the props when doing
/// const Func = (_props: { foo: string; bar?: number }) => ''
/// h(Func, {})
// otherwise it will default to `h(type: string)`
export function h<P, E extends EmitsOptions = {}>(
type: FunctionalComponent<P, E>,
props?: RenderProps<P, E>,
children?: RawChildren | RawSlots
): VNode
export function h(type: FunctionalComponent): VNode

// element
export function h(type: string, children?: RawChildren): VNode
export function h(
type: string,
props?: RawProps | null,
children?: RawChildren | RawSlots
): VNode

// fragment
export function h(type: typeof Fragment, children?: VNodeArrayChildren): VNode
export function h(
type: typeof Fragment,
props?: RawProps | null,
children?: VNodeArrayChildren
): VNode

// teleport (target prop is required)
export function h(
type: typeof Teleport,
props: RawProps & TeleportProps,
children: RawChildren
): VNode

// suspense
export function h(type: typeof Suspense, children?: RawChildren): VNode
export function h(
type: typeof Suspense,
props?: (RawProps & SuspenseProps) | null,
children?: RawChildren | RawSlots
): VNode

// catch-all for generic component types
export function h(type: Component, children?: RawChildren): VNode

// concrete component
export function h<P, E extends EmitsOptions = {}>(
type: ConcreteComponent<P, any, any, any, any, any, any, E> | string,
props?: RenderProps<P, E>,
children?: RawChildren
): VNode

export function h<P>(
type: ConcreteComponent | string,
children?: RawChildren
): VNode

// component without props
export function h(
type: Component,
props: null,
children?: RawChildren | RawSlots
): VNode

// // exclude `defineComponent` constructors
// export function h<P, E extends EmitsOptions = {}>(
Expand All @@ -171,17 +176,16 @@ type RenderProps<P, E extends EmitsOptions = {}> =
// children?: RawChildren | RawSlots
// ): VNode

// // fake constructor type returned by `defineComponent` or class component
// export function h(type: Constructor, children?: RawChildren): VNode
// export function h<P, E extends EmitsOptions = {}>(
// type: Constructor<P, E>,
// props?: (Partial<ExtractEmitEvents<E>> & RawProps & P) | ({} extends P ? null : never),
// children?: RawChildren | RawSlots
// ): ExtractEmitEvents<E>
// fake constructor type returned by `defineComponent` or class component
export function h<P, E extends EmitsOptions = {}>(
type: Constructor<P, E>,
props?: null,//RenderProps<P,E>,
children?: RawChildren | RawSlots
): ExtractEmitEvents<E>
export function h(type: Constructor, children?: RawChildren): VNode

// fake constructor type returned by `defineComponent`

export function h<P, E extends EmitsOptions = {}, PP = {}, Props = {} ,Defaults = {}>(
export function h<P, E extends EmitsOptions = {}, PP = {}, Props = {},Defaults = {}>(
type: DefineComponent<P, any, any, any, any, any, any, E, any, PP, Props, Defaults>,
props?: RenderProps<Partial<Defaults> & Omit<Props & PP, keyof Defaults>, E>,
children?: RawChildren | RawSlots
Expand Down
49 changes: 27 additions & 22 deletions test-dts/h.test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,16 @@ describe('h inference w/ functional component', () => {
h(Func, { foo: 'hello' })
h(Func, { foo: 'hello', bar: 123 })

h(Func, {
foo: '',
'onUpdate:bar'(v) {
expectType<number | undefined>(v)
},
'onUpdate:foo'(v) {
expectType<string>(v)
}
})

// @ts-expect-error
expectError(h(Func, { foo: 123 }))
// @ts-expect-error
Expand All @@ -93,39 +103,31 @@ describe('h support w/ plain object component', () => {
foo: String
}
}
h(Foo, { foo: 'ok' })
h(Foo, { foo: 'ok', class: 'extra' })
// no inference in this case

h(
{
emits: {
foo(a: number) {
return true
}
}
},
{
onFoo(s) {
expectType<number>(s)
}
h(Foo, {
foo: 'ok',
'onUpdate:foo'(v) {
expectType<string>(v)
}
)
})
h(Foo, {
foo: 'ok',
class: 'extra',

'onUpdate:foo'(v) {
expectType<string>(v)
}
})

// no inference in this case
h(
{
props: {
foo: String
},
emits: {
foo(a: number) {
return true
}
}
},
{
foo: 'ss',

onFoo(s) {
expectType<number>(s)
}
Expand Down Expand Up @@ -168,6 +170,9 @@ describe('h inference w/ defineComponent', () => {
expectError(h(Foo, { bar: 1, foo: 1 }))

const FooEmit = defineComponent({
props: {
foo: String
},
emits: {
foo(a: number) {
return true
Expand Down