import { isFunction } from '@vue/shared' ; import { currentInstance } from './component' ; import { currentRenderingInstance } from './componentRenderContext' ; import { warn } from './warning' ; export interface InjectionKey < T > extends Symbol { } export function provide < T > ( key , value ) { if ( ! currentInstance ) { if ( __DEV__ ) { warn ( `provide() can only be used inside setup().` ) ; } } else { let provides = currentInstance . provides ; const parentProvides = currentInstance . parent && currentInstance . parent . provides ; if ( parentProvides === provides ) { provides = currentInstance . provides = Object . create ( parentProvides ) ; } provides [ key as string ] = value ; } } export function inject < T > ( key ) ; export function inject < T > ( key , defaultValue , treatDefaultAsFactory ? ) ; export function inject < T > ( key , defaultValue , treatDefaultAsFactory ) ; export function inject ( key , defaultValue ? , treatDefaultAsFactory = false ) { const instance = currentInstance || currentRenderingInstance ; if ( instance ) { const provides = instance . parent == null ? instance . vnode . appContext && instance . vnode . appContext . provides : instance . parent . provides ; if ( provides && ( key as string | symbol ) in provides ) { return provides [ key as string ] ; } else if ( arguments . length > 1 ) { return treatDefaultAsFactory && isFunction ( defaultValue ) ? defaultValue . call ( instance . proxy ) : defaultValue ; } else if ( __DEV__ ) { warn ( `injection "${ String ( key ) }" not found.` ) ; } } else if ( __DEV__ ) { warn ( `inject() can only be used inside setup() or functional components.` ) ; } }