Skip to content
/ core Public
  • Sponsor vuejs/core

  • Notifications You must be signed in to change notification settings
  • Fork 8.6k
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

types(defineComponent): Support for GlobalComponents, typed Directives and respect expose on defineComponent #3399

Merged
merged 43 commits into from
Apr 25, 2024
Merged
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
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
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
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
3ecd0cb
Merge branch 'master-upstream' into types/refactor_defineComponent
pikax Jan 1, 2022
3757760
Merge branch 'main-upstream' into types/refactor_defineComponent
pikax Jan 27, 2022
37593c9
minor: fix ssrCompiler test
pikax Feb 5, 2022
b268011
minor: remove breaking code -.-'
pikax Feb 5, 2022
5b82ea4
Merge branch 'main-upstream' into types/refactor_defineComponent
pikax Feb 5, 2022
1269ab1
minor: fix tests and remove unnecessary defineComponent
pikax Feb 5, 2022
50b17d4
chore: remove added defineComponent
pikax Feb 5, 2022
90a5872
Merge branch 'main-upstream' into types/refactor_defineComponent
pikax May 11, 2022
fa99b42
fix bad merge
pikax May 11, 2022
a59d3c5
Merge branch 'main-upstream' into types/refactor_defineComponent
pikax May 12, 2022
30dd076
Merge branch 'main' into pr/3399
pikax Oct 21, 2023
6f0042e
[autofix.ci] apply automated fixes
autofix-ci[bot] Oct 21, 2023
f9754a6
format and remove comment
pikax Oct 21, 2023
9b98398
chore: remove RawOptions from defineComponent
pikax Oct 21, 2023
794f6c1
Merge branch 'main' into pr/3399
pikax Nov 17, 2023
34a5391
[autofix.ci] apply automated fixes
autofix-ci[bot] Nov 17, 2023
6eda2d5
chore: fix vuetify usage
pikax Nov 22, 2023
3b5b8f2
chore: Merge branch 'minor' into pr/3399
pikax Jan 21, 2024
93b94c2
Merge branch 'minor' into types/refactor_defineComponent
pikax Apr 17, 2024
af1c810
chore: Merge branch 'minor' into types/refactor_defineComponent
yyx990803 Apr 25, 2024
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
12 changes: 11 additions & 1 deletion packages/dts-test/componentTypeExtensions.test-d.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
import { defineComponent } from 'vue'
import { type DefineComponent, type Directive, defineComponent } from 'vue'
import { expectType } from './utils'

declare module 'vue' {
interface ComponentCustomOptions {
test?(n: number): void
}

interface GlobalDirectives {
test: Directive
}

interface GlobalComponents {
RouterView: DefineComponent<{}>
}

interface ComponentCustomProperties {
state?: 'stopped' | 'running'
}
@@ -46,6 +54,8 @@ export const Custom = defineComponent({
},
})

expectType<Directive>(Custom.directives!.test)
expectType<DefineComponent<{}>>(Custom.components!.RouterView)
expectType<JSX.Element>(<Custom baz={1} />)
expectType<JSX.Element>(<Custom custom={1} baz={1} />)
expectType<JSX.Element>(<Custom bar="bar" baz={1} />)
90 changes: 90 additions & 0 deletions packages/dts-test/defineComponent.test-d.tsx
Original file line number Diff line number Diff line change
@@ -1501,18 +1501,108 @@ describe('should work when props type is incompatible with setup returned type '

describe('withKeys and withModifiers as pro', () => {
const onKeydown = withKeys(e => {}, [''])
// @ts-expect-error invalid modifiers
const onClick = withModifiers(e => {}, [''])
;<input onKeydown={onKeydown} onClick={onClick} />
})

// #3367 expose components types
describe('expose component types', () => {
const child = defineComponent({
props: {
a: String,
},
})

const parent = defineComponent({
components: {
child,
child2: {
template: `<div></div>`,
},
},
})

expectType<typeof child>(parent.components!.child)
expectType<Component>(parent.components!.child2)

// global components
expectType<Readonly<KeepAliveProps>>(
new parent.components!.KeepAlive().$props,
)
expectType<Readonly<KeepAliveProps>>(new child.components!.KeepAlive().$props)

// runtime-dom components
expectType<Readonly<TransitionProps>>(
new parent.components!.Transition().$props,
)
expectType<Readonly<TransitionProps>>(
new child.components!.Transition().$props,
)
})

describe('directive typing', () => {
const customDirective: Directive = {
created(_) {},
}

const comp = defineComponent({
props: {
a: String,
},
directives: {
customDirective,
localDirective: {
created(_, { arg }) {
expectType<string | undefined>(arg)
},
},
},
})

expectType<typeof customDirective>(comp.directives!.customDirective)
expectType<Directive>(comp.directives!.localDirective)

// global directive
expectType<typeof vShow>(comp.directives!.vShow)
})

describe('expose typing', () => {
const Comp = defineComponent({
expose: ['a', 'b'],
props: {
some: String,
},
data() {
return { a: 1, b: '2', c: 1 }
},
})

expectType<Array<'a' | 'b'>>(Comp.expose!)

const vm = new Comp()
// internal should still be exposed
vm.$props

expectType<number>(vm.a)
expectType<string>(vm.b)

// @ts-expect-error shouldn't be exposed
vm.c
})

import type {
AllowedComponentProps,
ComponentCustomProps,
ComponentOptionsMixin,
DefineComponent,
Directive,
EmitsOptions,
ExtractPropTypes,
KeepAliveProps,
TransitionProps,
VNodeProps,
vShow,
} from 'vue'

// code generated by tsc / vue-tsc, make sure this continues to work
58 changes: 58 additions & 0 deletions packages/dts-test/directives.test-d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { type Directive, type ObjectDirective, vModelText } from 'vue'
import { describe, expectType } from './utils'

type ExtractBinding<T> = T extends (
el: any,
binding: infer B,
vnode: any,
prev: any,
) => any
? B
: never

declare function testDirective<
Value,
Modifiers extends string = string,
Arg extends string = string,
>(): ExtractBinding<Directive<any, Value, Modifiers, Arg>>

describe('vmodel', () => {
expectType<ObjectDirective<any, any, 'trim' | 'number' | 'lazy', string>>(
vModelText,
)
// @ts-expect-error
expectType<ObjectDirective<any, any, 'not-valid', string>>(vModelText)
})

describe('custom', () => {
expectType<{
value: number
oldValue: number | null
arg?: 'Arg'
modifiers: Record<'a' | 'b', boolean>
}>(testDirective<number, 'a' | 'b', 'Arg'>())

expectType<{
value: number
oldValue: number | null
arg?: 'Arg'
modifiers: Record<'a' | 'b', boolean>
// @ts-expect-error
}>(testDirective<number, 'a', 'Arg'>())

expectType<{
value: number
oldValue: number | null
arg?: 'Arg'
modifiers: Record<'a' | 'b', boolean>
// @ts-expect-error
}>(testDirective<number, 'a' | 'b', 'Argx'>())

expectType<{
value: number
oldValue: number | null
arg?: 'Arg'
modifiers: Record<'a' | 'b', boolean>
// @ts-expect-error
}>(testDirective<string, 'a' | 'b', 'Arg'>())
})
72 changes: 62 additions & 10 deletions packages/runtime-core/src/apiDefineComponent.ts
Original file line number Diff line number Diff line change
@@ -6,13 +6,17 @@ import type {
ComponentOptionsWithArrayProps,
ComponentOptionsWithObjectProps,
ComponentOptionsWithoutProps,
ComponentProvideOptions,
ComputedOptions,
MethodOptions,
RenderFunction,
} from './componentOptions'
import type {
AllowedComponentProps,
Component,
ComponentCustomProps,
GlobalComponents,
GlobalDirectives,
SetupContext,
} from './component'
import type {
@@ -29,6 +33,7 @@ import type {
CreateComponentPublicInstance,
} from './componentPublicInstance'
import type { SlotsType } from './componentSlots'
import type { Directive } from './directives'

export type PublicProps = VNodeProps &
AllowedComponentProps &
@@ -55,6 +60,10 @@ export type DefineComponent<
Props = ResolveProps<PropsOrPropOptions, E>,
Defaults = ExtractDefaultPropTypes<PropsOrPropOptions>,
S extends SlotsType = {},
LC extends Record<string, Component> = {},
Directives extends Record<string, Directive> = {},
Exposed extends string = string,
Provide extends ComponentProvideOptions = ComponentProvideOptions,
> = ComponentPublicInstanceConstructor<
CreateComponentPublicInstance<
Props,
@@ -69,7 +78,10 @@ export type DefineComponent<
Defaults,
true,
{},
S
S,
LC & GlobalComponents,
Directives & GlobalDirectives,
Exposed
>
> &
ComponentOptionsBase<
@@ -85,7 +97,11 @@ export type DefineComponent<
Defaults,
{},
string,
S
S,
LC & GlobalComponents,
Directives & GlobalDirectives,
Exposed,
Provide
> &
PP

@@ -166,9 +182,13 @@ export function defineComponent<
Extends extends ComponentOptionsMixin = ComponentOptionsMixin,
E extends EmitsOptions = {},
EE extends string = string,
S extends SlotsType = {},
I extends ComponentInjectOptions = {},
II extends string = string,
S extends SlotsType = {},
LC extends Record<string, Component> = {},
Directives extends Record<string, Directive> = {},
Exposed extends string = string,
Provide extends ComponentProvideOptions = ComponentProvideOptions,
>(
options: ComponentOptionsWithoutProps<
Props,
@@ -182,7 +202,11 @@ export function defineComponent<
EE,
I,
II,
S
S,
LC,
Directives,
Exposed,
Provide
>,
): DefineComponent<
Props,
@@ -197,7 +221,11 @@ export function defineComponent<
PublicProps,
ResolveProps<Props, E>,
ExtractDefaultPropTypes<Props>,
S
S,
LC,
Directives,
Exposed,
Provide
>

// overload 3: object format with array props declaration
@@ -216,6 +244,10 @@ export function defineComponent<
S extends SlotsType = {},
I extends ComponentInjectOptions = {},
II extends string = string,
LC extends Record<string, Component> = {},
Directives extends Record<string, Directive> = {},
Exposed extends string = string,
Provide extends ComponentProvideOptions = ComponentProvideOptions,
Props = Readonly<{ [key in PropNames]?: any }>,
>(
options: ComponentOptionsWithArrayProps<
@@ -230,7 +262,11 @@ export function defineComponent<
EE,
I,
II,
S
S,
LC,
Directives,
Exposed,
Provide
>,
): DefineComponent<
Props,
@@ -245,7 +281,11 @@ export function defineComponent<
PublicProps,
ResolveProps<Props, E>,
ExtractDefaultPropTypes<Props>,
S
S,
LC,
Directives,
Exposed,
Provide
>

// overload 4: object format with object props declaration
@@ -262,9 +302,13 @@ export function defineComponent<
Extends extends ComponentOptionsMixin = ComponentOptionsMixin,
E extends EmitsOptions = {},
EE extends string = string,
S extends SlotsType = {},
I extends ComponentInjectOptions = {},
II extends string = string,
S extends SlotsType = {},
LC extends Record<string, Component> = {},
Directives extends Record<string, Directive> = {},
Exposed extends string = string,
Provide extends ComponentProvideOptions = ComponentProvideOptions,
>(
options: ComponentOptionsWithObjectProps<
PropsOptions,
@@ -278,7 +322,11 @@ export function defineComponent<
EE,
I,
II,
S
S,
LC,
Directives,
Exposed,
Provide
>,
): DefineComponent<
PropsOptions,
@@ -293,7 +341,11 @@ export function defineComponent<
PublicProps,
ResolveProps<PropsOptions, E>,
ExtractDefaultPropTypes<PropsOptions>,
S
S,
LC,
Directives,
Exposed,
Provide
>

// implementation, close to no-op
Loading