eslint-plugin-vue icon indicating copy to clipboard operation
eslint-plugin-vue copied to clipboard

vue/return-in-computed-property requires return even if Typescript union type is exhausted in switch statement

Open larsmyrup opened this issue 2 years ago • 6 comments

Checklist

  • [x] I have tried restarting my IDE and the issue persists.
  • [x] I have read the FAQ and my problem is not listed.

Tell us about your environment

  • ESLint version: 8.39.0
  • eslint-plugin-vue version: 9.11.0
  • Node version: Problem in both v20.0.0 and v16.14.2
  • Operating System: macOS 13.3.1

Please show your full configuration:

/* eslint-env node */
require('@rushstack/eslint-patch/modern-module-resolution')

module.exports = {
  root: true,
  'extends': [
    'plugin:vue/vue3-essential',
    'eslint:recommended',
    '@vue/eslint-config-typescript'
  ],
  parserOptions: {
    ecmaVersion: 'latest'
  }
}

(Default Vue 3 setup)

What did you do?

<script setup lang="ts">
import { computed } from "vue";

interface Foo {
  category: 'foo'
}

interface Baz {
  category: 'baz'
}

type unionType = Foo | Baz

//Use Math random so typescript can't infer the type
const foo: unionType = Math.random() > 0.5 ? { category: 'foo' } : { category: 'baz' }

const computedStuff = computed(() => {  //This is the line that throws the error
  switch (foo.category) {
    case 'foo':
      return 'foo'
    case 'baz':
      return 'baz'
  }
})

</script>

What did you expect to happen? Expected ESLint to recognize that the switch exhausts the union type and therefore a value would always be returned

What actually happened?

  17:32  error  Expected to return a value in computed function  vue/return-in-computed-property

ESLint complains and says the computed property is missing a return value.

Repository to reproduce this issue https://github.com/Larsmyrup/return-in-computed-property-bug-repro

Let me know if i need to elaborate on anything

larsmyrup avatar May 02 '23 15:05 larsmyrup

See also https://typescript-eslint.io/rules/switch-exhaustiveness-check

FloEdelmann avatar May 02 '23 15:05 FloEdelmann

A workaround right now would be

default: {
  // Make ts check the default case is never reached
  foo.category satisfies never;
  // Throw to placate vue/return-in-computed-property
  throw new Error('Unreachable');
}

hfhchan-plb avatar Aug 27 '23 06:08 hfhchan-plb

Actually, no, the workaround in https://github.com/vuejs/eslint-plugin-vue/issues/2100#issuecomment-1455242833 is far superior: extract the switch case to a separate function.

hfhchan-plb avatar Aug 27 '23 09:08 hfhchan-plb

+1, I have been frustrated by this for some time.

For me, the ideal behaviour of this rule in a typescript context would be, if it finds that the computed property has an explicit non-void return type, that's sufficient to satisfy the rule—let typescript do the rest.

baffalop avatar Nov 21 '23 07:11 baffalop

The rule is still reporting false positives for exhausted cases. Any plans to fix it?

hymair avatar Jun 11 '24 06:06 hymair

A pull request to improve the detection is welcome

FloEdelmann avatar Jun 11 '24 11:06 FloEdelmann