Composition-api: How to tell typescript that the result of inject won't be void?

Created on 25 Dec 2019  路  3Comments  路  Source: vuejs/composition-api

I'm using provide/inject like this:

// in common symbols.ts file
export const TableSymbol: InjectionKey<InstanceType<VueConstructor>> = Symbol()

// in root component setup()
provide(TableSymbol, getCurrentInstance())

// in child component setup()
const $table = inject(TableSymbol)

$table.$on('event', eventHandler) // <---- TS2339 error

Typescript shows following error on above line:

TS2339: Property '$on' does not exist on type 'void | CombinedVueInstance<Vue, object, object, object, Record<never, any>>'.
Property '$on' does not exist on type 'void'.

How should I tell typescript that $table is not of void type?

Most helpful comment

i think inject should return T instead of T | void and the lib can warn to user if not injected, has a void type only make more verbose the usage of inject and InjectionKey lost purpose because we need always do a type casting

All 3 comments

Well, it can be void, namely if you use the component in a place that's not a (grand)child of the component doing the provide.

So it would be good practice to actually account for that:

const $table = inject(TableSymbol)
if (!$table) {
  throw new Error('provide missing')
}
// For code following this, Typescript will know that $table will exist.

This is a ts question not related to the library, it shouldn't be asked here.

Usually using an explicit type annotation for $table or using the non-null assertion operator !:

const $table = inject(TableSymbol)!
const $table = inject(TableSymbol) as Table

i think inject should return T instead of T | void and the lib can warn to user if not injected, has a void type only make more verbose the usage of inject and InjectionKey lost purpose because we need always do a type casting

Was this page helpful?
0 / 5 - 0 ratings