mirror of https://github.com/vuejs/core.git
fix(types): support inferring injected properties in options api (#6804)
close #3031 close #5931
This commit is contained in:
parent
50e2253057
commit
e4de623ea7
|
@ -6,7 +6,8 @@ import {
|
|||
ComponentOptionsWithObjectProps,
|
||||
ComponentOptionsMixin,
|
||||
RenderFunction,
|
||||
ComponentOptionsBase
|
||||
ComponentOptionsBase,
|
||||
ComponentInjectOptions
|
||||
} from './componentOptions'
|
||||
import {
|
||||
SetupContext,
|
||||
|
@ -104,7 +105,9 @@ export function defineComponent<
|
|||
Mixin extends ComponentOptionsMixin = ComponentOptionsMixin,
|
||||
Extends extends ComponentOptionsMixin = ComponentOptionsMixin,
|
||||
E extends EmitsOptions = {},
|
||||
EE extends string = string
|
||||
EE extends string = string,
|
||||
I extends ComponentInjectOptions = {},
|
||||
II extends string = string
|
||||
>(
|
||||
options: ComponentOptionsWithoutProps<
|
||||
Props,
|
||||
|
@ -115,7 +118,9 @@ export function defineComponent<
|
|||
Mixin,
|
||||
Extends,
|
||||
E,
|
||||
EE
|
||||
EE,
|
||||
I,
|
||||
II
|
||||
>
|
||||
): DefineComponent<Props, RawBindings, D, C, M, Mixin, Extends, E, EE>
|
||||
|
||||
|
@ -131,7 +136,9 @@ export function defineComponent<
|
|||
Mixin extends ComponentOptionsMixin = ComponentOptionsMixin,
|
||||
Extends extends ComponentOptionsMixin = ComponentOptionsMixin,
|
||||
E extends EmitsOptions = {},
|
||||
EE extends string = string
|
||||
EE extends string = string,
|
||||
I extends ComponentInjectOptions = {},
|
||||
II extends string = string,
|
||||
>(
|
||||
options: ComponentOptionsWithArrayProps<
|
||||
PropNames,
|
||||
|
@ -142,7 +149,9 @@ export function defineComponent<
|
|||
Mixin,
|
||||
Extends,
|
||||
E,
|
||||
EE
|
||||
EE,
|
||||
I,
|
||||
II
|
||||
>
|
||||
): DefineComponent<
|
||||
Readonly<{ [key in PropNames]?: any }>,
|
||||
|
@ -169,7 +178,9 @@ export function defineComponent<
|
|||
Mixin extends ComponentOptionsMixin = ComponentOptionsMixin,
|
||||
Extends extends ComponentOptionsMixin = ComponentOptionsMixin,
|
||||
E extends EmitsOptions = {},
|
||||
EE extends string = string
|
||||
EE extends string = string,
|
||||
I extends ComponentInjectOptions = {},
|
||||
II extends string = string,
|
||||
>(
|
||||
options: ComponentOptionsWithObjectProps<
|
||||
PropsOptions,
|
||||
|
@ -180,7 +191,9 @@ export function defineComponent<
|
|||
Mixin,
|
||||
Extends,
|
||||
E,
|
||||
EE
|
||||
EE,
|
||||
I,
|
||||
II
|
||||
>
|
||||
): DefineComponent<PropsOptions, RawBindings, D, C, M, Mixin, Extends, E, EE>
|
||||
|
||||
|
|
|
@ -118,8 +118,10 @@ export interface ComponentOptionsBase<
|
|||
Extends extends ComponentOptionsMixin,
|
||||
E extends EmitsOptions,
|
||||
EE extends string = string,
|
||||
Defaults = {}
|
||||
> extends LegacyOptions<Props, D, C, M, Mixin, Extends>,
|
||||
Defaults = {},
|
||||
I extends ComponentInjectOptions = {},
|
||||
II extends string = string
|
||||
> extends LegacyOptions<Props, D, C, M, Mixin, Extends, I, II>,
|
||||
ComponentInternalOptions,
|
||||
ComponentCustomOptions {
|
||||
setup?: (
|
||||
|
@ -225,7 +227,9 @@ export type ComponentOptionsWithoutProps<
|
|||
Extends extends ComponentOptionsMixin = ComponentOptionsMixin,
|
||||
E extends EmitsOptions = EmitsOptions,
|
||||
EE extends string = string,
|
||||
PE = Props & EmitsToProps<E>
|
||||
I extends ComponentInjectOptions = {},
|
||||
II extends string = string,
|
||||
PE = Props & EmitsToProps<E>,
|
||||
> = ComponentOptionsBase<
|
||||
PE,
|
||||
RawBindings,
|
||||
|
@ -236,11 +240,13 @@ export type ComponentOptionsWithoutProps<
|
|||
Extends,
|
||||
E,
|
||||
EE,
|
||||
{}
|
||||
{},
|
||||
I,
|
||||
II
|
||||
> & {
|
||||
props?: undefined
|
||||
} & ThisType<
|
||||
CreateComponentPublicInstance<PE, RawBindings, D, C, M, Mixin, Extends, E>
|
||||
CreateComponentPublicInstance<PE, RawBindings, D, C, M, Mixin, Extends, E, PE, {}, false, I>
|
||||
>
|
||||
|
||||
export type ComponentOptionsWithArrayProps<
|
||||
|
@ -253,6 +259,8 @@ export type ComponentOptionsWithArrayProps<
|
|||
Extends extends ComponentOptionsMixin = ComponentOptionsMixin,
|
||||
E extends EmitsOptions = EmitsOptions,
|
||||
EE extends string = string,
|
||||
I extends ComponentInjectOptions = {},
|
||||
II extends string = string,
|
||||
Props = Readonly<{ [key in PropNames]?: any }> & EmitsToProps<E>
|
||||
> = ComponentOptionsBase<
|
||||
Props,
|
||||
|
@ -264,7 +272,9 @@ export type ComponentOptionsWithArrayProps<
|
|||
Extends,
|
||||
E,
|
||||
EE,
|
||||
{}
|
||||
{},
|
||||
I,
|
||||
II
|
||||
> & {
|
||||
props: PropNames[]
|
||||
} & ThisType<
|
||||
|
@ -276,7 +286,11 @@ export type ComponentOptionsWithArrayProps<
|
|||
M,
|
||||
Mixin,
|
||||
Extends,
|
||||
E
|
||||
E,
|
||||
Props,
|
||||
{},
|
||||
false,
|
||||
I
|
||||
>
|
||||
>
|
||||
|
||||
|
@ -290,8 +304,10 @@ export type ComponentOptionsWithObjectProps<
|
|||
Extends extends ComponentOptionsMixin = ComponentOptionsMixin,
|
||||
E extends EmitsOptions = EmitsOptions,
|
||||
EE extends string = string,
|
||||
I extends ComponentInjectOptions = {},
|
||||
II extends string = string,
|
||||
Props = Readonly<ExtractPropTypes<PropsOptions>> & EmitsToProps<E>,
|
||||
Defaults = ExtractDefaultPropTypes<PropsOptions>
|
||||
Defaults = ExtractDefaultPropTypes<PropsOptions>,
|
||||
> = ComponentOptionsBase<
|
||||
Props,
|
||||
RawBindings,
|
||||
|
@ -302,7 +318,9 @@ export type ComponentOptionsWithObjectProps<
|
|||
Extends,
|
||||
E,
|
||||
EE,
|
||||
Defaults
|
||||
Defaults,
|
||||
I,
|
||||
II
|
||||
> & {
|
||||
props: PropsOptions & ThisType<void>
|
||||
} & ThisType<
|
||||
|
@ -317,7 +335,8 @@ export type ComponentOptionsWithObjectProps<
|
|||
E,
|
||||
Props,
|
||||
Defaults,
|
||||
false
|
||||
false,
|
||||
I
|
||||
>
|
||||
>
|
||||
|
||||
|
@ -389,20 +408,32 @@ export type ComponentProvideOptions = ObjectProvideOptions | Function
|
|||
|
||||
type ObjectProvideOptions = Record<string | symbol, unknown>
|
||||
|
||||
type ComponentInjectOptions = string[] | ObjectInjectOptions
|
||||
export type ComponentInjectOptions = string[] | ObjectInjectOptions
|
||||
|
||||
type ObjectInjectOptions = Record<
|
||||
string | symbol,
|
||||
string | symbol | { from?: string | symbol; default?: unknown }
|
||||
>
|
||||
|
||||
export type InjectToObject<T extends ComponentInjectOptions> = T extends string[]
|
||||
? {
|
||||
[K in T[number]]?: unknown
|
||||
}
|
||||
: T extends ObjectInjectOptions
|
||||
? {
|
||||
[K in keyof T]?: unknown
|
||||
}
|
||||
: never
|
||||
|
||||
interface LegacyOptions<
|
||||
Props,
|
||||
D,
|
||||
C extends ComputedOptions,
|
||||
M extends MethodOptions,
|
||||
Mixin extends ComponentOptionsMixin,
|
||||
Extends extends ComponentOptionsMixin
|
||||
Extends extends ComponentOptionsMixin,
|
||||
I extends ComponentInjectOptions,
|
||||
II extends string
|
||||
> {
|
||||
compatConfig?: CompatConfig
|
||||
|
||||
|
@ -437,7 +468,7 @@ interface LegacyOptions<
|
|||
methods?: M
|
||||
watch?: ComponentWatchOptions
|
||||
provide?: ComponentProvideOptions
|
||||
inject?: ComponentInjectOptions
|
||||
inject?: I | II[]
|
||||
|
||||
// assets
|
||||
filters?: Record<string, Function>
|
||||
|
|
|
@ -34,7 +34,9 @@ import {
|
|||
OptionTypesKeys,
|
||||
resolveMergedOptions,
|
||||
shouldCacheAccess,
|
||||
MergedComponentOptionsOverride
|
||||
MergedComponentOptionsOverride,
|
||||
InjectToObject,
|
||||
ComponentInjectOptions
|
||||
} from './componentOptions'
|
||||
import { EmitsOptions, EmitFn } from './componentEmits'
|
||||
import { Slots } from './componentSlots'
|
||||
|
@ -141,6 +143,7 @@ export type CreateComponentPublicInstance<
|
|||
PublicProps = P,
|
||||
Defaults = {},
|
||||
MakeDefaultsOptional extends boolean = false,
|
||||
I extends ComponentInjectOptions = {},
|
||||
PublicMixin = IntersectionMixin<Mixin> & IntersectionMixin<Extends>,
|
||||
PublicP = UnwrapMixinsType<PublicMixin, 'P'> & EnsureNonVoid<P>,
|
||||
PublicB = UnwrapMixinsType<PublicMixin, 'B'> & EnsureNonVoid<B>,
|
||||
|
@ -150,7 +153,7 @@ export type CreateComponentPublicInstance<
|
|||
PublicM extends MethodOptions = UnwrapMixinsType<PublicMixin, 'M'> &
|
||||
EnsureNonVoid<M>,
|
||||
PublicDefaults = UnwrapMixinsType<PublicMixin, 'Defaults'> &
|
||||
EnsureNonVoid<Defaults>
|
||||
EnsureNonVoid<Defaults>,
|
||||
> = ComponentPublicInstance<
|
||||
PublicP,
|
||||
PublicB,
|
||||
|
@ -161,7 +164,8 @@ export type CreateComponentPublicInstance<
|
|||
PublicProps,
|
||||
PublicDefaults,
|
||||
MakeDefaultsOptional,
|
||||
ComponentOptionsBase<P, B, D, C, M, Mixin, Extends, E, string, Defaults>
|
||||
ComponentOptionsBase<P, B, D, C, M, Mixin, Extends, E, string, Defaults>,
|
||||
I
|
||||
>
|
||||
|
||||
// public properties exposed on the proxy, which is used as the render context
|
||||
|
@ -176,7 +180,8 @@ export type ComponentPublicInstance<
|
|||
PublicProps = P,
|
||||
Defaults = {},
|
||||
MakeDefaultsOptional extends boolean = false,
|
||||
Options = ComponentOptionsBase<any, any, any, any, any, any, any, any, any>
|
||||
Options = ComponentOptionsBase<any, any, any, any, any, any, any, any, any>,
|
||||
I extends ComponentInjectOptions = {}
|
||||
> = {
|
||||
$: ComponentInternalInstance
|
||||
$data: D
|
||||
|
@ -205,7 +210,8 @@ export type ComponentPublicInstance<
|
|||
UnwrapNestedRefs<D> &
|
||||
ExtractComputedReturns<C> &
|
||||
M &
|
||||
ComponentCustomProperties
|
||||
ComponentCustomProperties &
|
||||
InjectToObject<I>
|
||||
|
||||
export type PublicPropertiesMap = Record<
|
||||
string,
|
||||
|
|
|
@ -222,7 +222,8 @@ export {
|
|||
RenderFunction,
|
||||
MethodOptions,
|
||||
ComputedOptions,
|
||||
RuntimeCompilerOptions
|
||||
RuntimeCompilerOptions,
|
||||
ComponentInjectOptions
|
||||
} from './componentOptions'
|
||||
export { EmitsOptions, ObjectEmitsOptions } from './componentEmits'
|
||||
export {
|
||||
|
|
|
@ -19,7 +19,8 @@ import {
|
|||
nextTick,
|
||||
warn,
|
||||
ConcreteComponent,
|
||||
ComponentOptions
|
||||
ComponentOptions,
|
||||
ComponentInjectOptions
|
||||
} from '@vue/runtime-core'
|
||||
import { camelize, extend, hyphenate, isArray, toNumber } from '@vue/shared'
|
||||
import { hydrate, render } from '.'
|
||||
|
@ -49,7 +50,9 @@ export function defineCustomElement<
|
|||
Mixin extends ComponentOptionsMixin = ComponentOptionsMixin,
|
||||
Extends extends ComponentOptionsMixin = ComponentOptionsMixin,
|
||||
E extends EmitsOptions = EmitsOptions,
|
||||
EE extends string = string
|
||||
EE extends string = string,
|
||||
I extends ComponentInjectOptions = {},
|
||||
II extends string = string
|
||||
>(
|
||||
options: ComponentOptionsWithoutProps<
|
||||
Props,
|
||||
|
@ -60,7 +63,9 @@ export function defineCustomElement<
|
|||
Mixin,
|
||||
Extends,
|
||||
E,
|
||||
EE
|
||||
EE,
|
||||
I,
|
||||
II
|
||||
> & { styles?: string[] }
|
||||
): VueElementConstructor<Props>
|
||||
|
||||
|
@ -74,7 +79,9 @@ export function defineCustomElement<
|
|||
Mixin extends ComponentOptionsMixin = ComponentOptionsMixin,
|
||||
Extends extends ComponentOptionsMixin = ComponentOptionsMixin,
|
||||
E extends EmitsOptions = Record<string, any>,
|
||||
EE extends string = string
|
||||
EE extends string = string,
|
||||
I extends ComponentInjectOptions = {},
|
||||
II extends string = string
|
||||
>(
|
||||
options: ComponentOptionsWithArrayProps<
|
||||
PropNames,
|
||||
|
@ -85,7 +92,9 @@ export function defineCustomElement<
|
|||
Mixin,
|
||||
Extends,
|
||||
E,
|
||||
EE
|
||||
EE,
|
||||
I,
|
||||
II
|
||||
> & { styles?: string[] }
|
||||
): VueElementConstructor<{ [K in PropNames]: any }>
|
||||
|
||||
|
@ -99,7 +108,9 @@ export function defineCustomElement<
|
|||
Mixin extends ComponentOptionsMixin = ComponentOptionsMixin,
|
||||
Extends extends ComponentOptionsMixin = ComponentOptionsMixin,
|
||||
E extends EmitsOptions = Record<string, any>,
|
||||
EE extends string = string
|
||||
EE extends string = string,
|
||||
I extends ComponentInjectOptions = {},
|
||||
II extends string = string
|
||||
>(
|
||||
options: ComponentOptionsWithObjectProps<
|
||||
PropsOptions,
|
||||
|
@ -110,7 +121,9 @@ export function defineCustomElement<
|
|||
Mixin,
|
||||
Extends,
|
||||
E,
|
||||
EE
|
||||
EE,
|
||||
I,
|
||||
II
|
||||
> & { styles?: string[] }
|
||||
): VueElementConstructor<ExtractPropTypes<PropsOptions>>
|
||||
|
||||
|
|
|
@ -1033,6 +1033,68 @@ describe('emits', () => {
|
|||
})
|
||||
})
|
||||
|
||||
describe('inject', () => {
|
||||
// with object inject
|
||||
defineComponent({
|
||||
props: {
|
||||
a: String
|
||||
},
|
||||
inject: {
|
||||
foo: 'foo',
|
||||
bar: 'bar',
|
||||
},
|
||||
created() {
|
||||
expectType<unknown>(this.foo)
|
||||
expectType<unknown>(this.bar)
|
||||
// @ts-expect-error
|
||||
expectError(this.foobar = 1)
|
||||
}
|
||||
})
|
||||
|
||||
// with array inject
|
||||
defineComponent({
|
||||
props: ['a', 'b'],
|
||||
inject: ['foo', 'bar'],
|
||||
created() {
|
||||
expectType<unknown>(this.foo)
|
||||
expectType<unknown>(this.bar)
|
||||
// @ts-expect-error
|
||||
expectError(this.foobar = 1)
|
||||
}
|
||||
})
|
||||
|
||||
// with no props
|
||||
defineComponent({
|
||||
inject: {
|
||||
foo: {
|
||||
from: 'pfoo',
|
||||
default: 'foo'
|
||||
},
|
||||
bar: {
|
||||
from: 'pbar',
|
||||
default: 'bar'
|
||||
},
|
||||
},
|
||||
created() {
|
||||
expectType<unknown>(this.foo)
|
||||
expectType<unknown>(this.bar)
|
||||
// @ts-expect-error
|
||||
expectError(this.foobar = 1)
|
||||
}
|
||||
})
|
||||
|
||||
// without inject
|
||||
defineComponent({
|
||||
props: ['a', 'b'],
|
||||
created() {
|
||||
// @ts-expect-error
|
||||
expectError(this.foo = 1)
|
||||
// @ts-expect-error
|
||||
expectError(this.bar = 1)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
describe('componentOptions setup should be `SetupContext`', () => {
|
||||
expectType<ComponentOptions['setup']>(
|
||||
{} as (props: Record<string, any>, ctx: SetupContext) => any
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
import { defineCustomElement, expectType, expectError } from './index'
|
||||
|
||||
describe('inject', () => {
|
||||
// with object inject
|
||||
defineCustomElement({
|
||||
props: {
|
||||
a: String
|
||||
},
|
||||
inject: {
|
||||
foo: 'foo',
|
||||
bar: 'bar',
|
||||
},
|
||||
created() {
|
||||
expectType<unknown>(this.foo)
|
||||
expectType<unknown>(this.bar)
|
||||
// @ts-expect-error
|
||||
expectError(this.foobar = 1)
|
||||
}
|
||||
})
|
||||
|
||||
// with array inject
|
||||
defineCustomElement({
|
||||
props: ['a', 'b'],
|
||||
inject: ['foo', 'bar'],
|
||||
created() {
|
||||
expectType<unknown>(this.foo)
|
||||
expectType<unknown>(this.bar)
|
||||
// @ts-expect-error
|
||||
expectError(this.foobar = 1)
|
||||
}
|
||||
})
|
||||
|
||||
// with no props
|
||||
defineCustomElement({
|
||||
inject: {
|
||||
foo: {
|
||||
from: 'pbar',
|
||||
default: 'foo'
|
||||
},
|
||||
bar: {
|
||||
from: 'pfoo',
|
||||
default: 'bar'
|
||||
},
|
||||
},
|
||||
created() {
|
||||
expectType<unknown>(this.foo)
|
||||
expectType<unknown>(this.bar)
|
||||
// @ts-expect-error
|
||||
expectError(this.foobar = 1)
|
||||
}
|
||||
})
|
||||
|
||||
// without inject
|
||||
defineCustomElement({
|
||||
props: ['a', 'b'],
|
||||
created() {
|
||||
// @ts-expect-error
|
||||
expectError(this.foo = 1)
|
||||
// @ts-expect-error
|
||||
expectError(this.bar = 1)
|
||||
}
|
||||
})
|
||||
})
|
Loading…
Reference in New Issue