Closed bartenra closed 3 years ago
Does Volar extension show this error?
I was too fast to post. My minimal reproducible case actually doesn't give this error.
@bartenra I have the exact same problem. How did you solve it?
@tschoartschi Are you using Volar?
@bartenra no currently I use Vetur. Since I need it for work and this project is only a side project I didn't want to crash my work environment with installing a new extension for Vue development.
But the good news is, I figured out the problem 🎉 I try to quickly explain what the problem was. Let's have a look at the following code:
export default defineComponent({
setup() {
const handler = inject<Handler>('handler');
const method1 = () => handler.runTask();
return {
method1,
};
});
Now TypeScript complained that handler
could be undefined. Then I added a null-check:
export default defineComponent({
setup() {
const handler = inject<Handler>('handler');
if(!handler) {
console.error('no handler defined');
return;
}
const method1 = () => handler.runTask();
return {
method1,
};
});
Now TypeScript didn't complain while developing. But when I did the production build of course it caused problems because there is the possibility that the setup
method returns undefined. Of course, this is easy to spot in this short example but the real code was more involved. So it took some time to find the problem. The error message was also not helpful because vue-tsc
only said:
src/components/Example.vue:9:18 - error TS2304: Cannot find name 'method1'.
9 @change="method1"
Since in my case handler
is always defined I did the following:
const handler = inject<Handler>('handler')!; // add "!" at the end to tell TypeScript that handler is always defined
Now everyone is happy and the build works again 🎉
@tschoartschi I think that is a bit of an escape hatch. After all, it might not be defined if you forgot to provide
it in a parent component.
You might find this helpful: https://logaretm.com/blog/2020-12-23-type-safe-provide-inject/
@bartenra thanks for the link 🙂 it's a very interesting read and especially injectStrict
is a nice solution for our problem. In our case, the object is really always defined because it's a singleton that is available in the whole application. But this injectStrict
will make the code definitely better.
Does not error:
Wrongly errors: