ComponentOptionsWithObjectProps,
ComponentOptionsMixin,
RenderFunction,
- ComponentOptionsBase
+ ComponentOptionsBase,
+ ComponentInjectOptions
} from './componentOptions'
import {
SetupContext,
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,
Mixin,
Extends,
E,
- EE
+ EE,
+ I,
+ II
>
): DefineComponent<Props, RawBindings, D, C, M, Mixin, Extends, E, EE>
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,
Mixin,
Extends,
E,
- EE
+ EE,
+ I,
+ II
>
): DefineComponent<
Readonly<{ [key in PropNames]?: any }>,
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,
Mixin,
Extends,
E,
- EE
+ EE,
+ I,
+ II
>
): DefineComponent<PropsOptions, RawBindings, D, C, M, Mixin, Extends, E, EE>
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?: (
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,
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<
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,
Extends,
E,
EE,
- {}
+ {},
+ I,
+ II
> & {
props: PropNames[]
} & ThisType<
M,
Mixin,
Extends,
- E
+ E,
+ Props,
+ {},
+ false,
+ I
>
>
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,
Extends,
E,
EE,
- Defaults
+ Defaults,
+ I,
+ II
> & {
props: PropsOptions & ThisType<void>
} & ThisType<
E,
Props,
Defaults,
- false
+ false,
+ I
>
>
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
methods?: M
watch?: ComponentWatchOptions
provide?: ComponentProvideOptions
- inject?: ComponentInjectOptions
+ inject?: I | II[]
// assets
filters?: Record<string, Function>
OptionTypesKeys,
resolveMergedOptions,
shouldCacheAccess,
- MergedComponentOptionsOverride
+ MergedComponentOptionsOverride,
+ InjectToObject,
+ ComponentInjectOptions
} from './componentOptions'
import { EmitsOptions, EmitFn } from './componentEmits'
import { Slots } from './componentSlots'
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>,
PublicM extends MethodOptions = UnwrapMixinsType<PublicMixin, 'M'> &
EnsureNonVoid<M>,
PublicDefaults = UnwrapMixinsType<PublicMixin, 'Defaults'> &
- EnsureNonVoid<Defaults>
+ EnsureNonVoid<Defaults>,
> = ComponentPublicInstance<
PublicP,
PublicB,
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
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
UnwrapNestedRefs<D> &
ExtractComputedReturns<C> &
M &
- ComponentCustomProperties
+ ComponentCustomProperties &
+ InjectToObject<I>
export type PublicPropertiesMap = Record<
string,
RenderFunction,
MethodOptions,
ComputedOptions,
- RuntimeCompilerOptions
+ RuntimeCompilerOptions,
+ ComponentInjectOptions
} from './componentOptions'
export { EmitsOptions, ObjectEmitsOptions } from './componentEmits'
export {
nextTick,
warn,
ConcreteComponent,
- ComponentOptions
+ ComponentOptions,
+ ComponentInjectOptions
} from '@vue/runtime-core'
import { camelize, extend, hyphenate, isArray, toNumber } from '@vue/shared'
import { hydrate, render } from '.'
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,
Mixin,
Extends,
E,
- EE
+ EE,
+ I,
+ II
> & { styles?: string[] }
): VueElementConstructor<Props>
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,
Mixin,
Extends,
E,
- EE
+ EE,
+ I,
+ II
> & { styles?: string[] }
): VueElementConstructor<{ [K in PropNames]: any }>
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,
Mixin,
Extends,
E,
- EE
+ EE,
+ I,
+ II
> & { styles?: string[] }
): VueElementConstructor<ExtractPropTypes<PropsOptions>>
})
})
+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
--- /dev/null
+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)
+ }
+ })
+})
\ No newline at end of file