Vue's computed property utilizing typed variables

I am trying to create a computed array of type Todo[], but I keep encountering this specific error:

No overload matches this call. Overload 1 of 2, '(getter: ComputedGetter<Todo[]>, debugOptions?: DebuggerOptions | undefined): ComputedRef<Todo[]>', gave the following error. Overload 2 of 2, '(options: WritableComputedOptions<Todo[]>, debugOptions?: DebuggerOptions | undefined): WritableComputedRef<Todo[]>', gave the following error.

This is what I have attempted so far:

todo.ts

export class Todo {
  checked: boolean;
  text: string
 
  constructor(checked: boolean, text: string) {
    this.checked = checked;
    this.text = text
  }
}

Todos.vue

<script setup lang="ts">
import { computed } from '@vue/reactivity';
import { ref } from 'vue'
import { Todo } from '../todo'

let todos = ref<Todo[]>([]);

const filter = ref<string>('all')
const filteredTodos = computed<Todo[]>(() => {
  if(filter.value == "all") return todos;
  if(filter.value == "active") return todos.value.filter((item) => !item.checked)
  if(filter.value == "completed") return todos.value.filter((item) => item.checked)
})
</script>

Answer №1

TypeScript is the way to go.

With three conditions and returning Todo[] each time, TypeScript may not recognize that all cases are covered by those conditions. In case none of them are met, the result returned will be undefined.

To ensure TypeScript understands this, you can do something like:

const filteredTodos = computed<Todo[]>(() => {
  if (filter.value === "active")
    return todos.value.filter((item) => !item.checked)
  if (filter.value === "completed")
    return todos.value.filter((item) => item.checked)

  // cover all other cases:
  return todos.value
})

This could also be simplified as:

const filteredTodos = computed<Todo[]>(() =>
  filter.value === "active"
    ? todos.value.filter((item) => !item.checked)
    : filter.value === "completed"
      ? todos.value.filter((item) => item.checked)
      : todos.value
)

For better readability:

const filteredTodos = computed<Todo[]>(() => {
  switch (true) {
    case filter.value === "active":
      return todos.value.filter((item) => !item.checked)
    case filter.value === "completed":
      return todos.value.filter((item) => item.checked)
    default:
      return todos.value
  }
})

Notes:

  • I've updated loose equality to strict equality for better coding practices. Loose equality can lead to bugs that are hard to detect.
  • In the adjusted logic, the computed now returns all todos unless filter.value is either 'active' or 'completed'. The 'all' filter value is implied and no longer needs to be specified. If you prefer to return an empty array when the filter value is unspecified, you can use:
const filteredTodos = computed<Todo[]>(() => {
  switch (true) {
    case filter.value === "all":
      return todos.value
    case filter.value === "active":
      return todos.value.filter((item) => !item.checked)
    case filter.value === "completed":
      return todos.value.filter((item) => item.checked)
    default:
      return []
  }
})

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Retrieve information dynamically from a JSON file using the get JSON function and iterate through the data

I possess a JSON file that I wish to utilize in creating dynamic HTML elements with the JSON content. Below is the provided JSON data: { "india": [ { "position": "left", "imgurl":"3.jpg" }, { ...

Exploring ways to retrieve a function-scoped variable from within an Angular subscribe function

Here's the scenario: I have a simple question regarding an Angular component. Inside this component, there is a function structured like this: somethingCollection: TypeSomething[] ... public deleteSomething(something: TypeSomething): void { // so ...

What is the best method for animating a display table to none or reducing its height to

My goal is to animate a header whenever the class collapseTest is applied. After some trial and error, I have come up with the following solution: http://jsfiddle.net/robertrozas/atuyLtL0/1/. A big shoutout to @Hackerman for helping me get it to work. The ...

Use jQuery to parse the JSON below and then showcase the information in an HTML table

Can anyone assist me with parsing the following JSON using jQuery and presenting it in an HTML table? I want to showcase the values of "key" and "doc_count" in an HTML table. Your help would be greatly appreciated. Please find the JSON data below: { ...

The scrolling speed of the mousewheel in Firefox is notably slower compared to that of Google Chrome

Kindly review this sample link: When I test the above example in Chrome and scroll using the mouse wheel, the page moves up by 100px each time. The Y position is displayed as well. However, if I try the same page in Firefox 26.0 and scroll with the mouse ...

Why is the child's CSS hover not functioning when the body has an event listener attached to it?

Check out the repository link here: https://codepen.io/Jaycethanks/pen/WNJqdWB I am trying to achieve a parallax effect on the body and image container, as well as a scale-up effect on images when hovered over. However, the hover functionality is not work ...

Move the location of the mouse click to a different spot

I recently received an unusual request for the app I'm developing. The requirement is to trigger a mouse click event 50 pixels to the right of the current cursor position when the user clicks. Is there a way to achieve this? ...

Tips on resolving the issue of an Axios post request not appearing in a get request in React

When using axios to make a post request in this code, a new username is posted, but there is an issue with retrieving the posted name from the API. How can I fix this problem to view my posted request? const App = () => { const [data, setData] = u ...

How to align an unordered list vertically in the center using Bootstrap?

Trying to figure out why the ul within this parent div is not centered vertically. Here is a screenshot of the issue: https://i.sstatic.net/ZOc9M.png <div className=" d-flex align-items-center bg-primary "> <ul ...

Is it feasible to stop closure from capturing external variables in TypeScript?

Imagine I have the following piece of Typescript code: const a = 456 const b = () => a Is there a way to make the Typescript compiler detect and flag an error or warning during compilation indicating that function b is accessing an external variable a ...

The JavaScript code snippets are ineffective, yielding an error message of "resource failed to load."

<? echo '<html> <script language=javascript> function validate() { alert("validate"); document.form1.action="validate.php"; document.form1.submit(); return false; } function del() { alert("delete"); document.form ...

Navigate to a particular date with react-big-calendar

I know this might sound like a silly question, but I am new to working with React. Currently, the React-big-calendar allows users to navigate to specific dates when selected from the Month view. What I want is for the same functionality to apply when a use ...

Tips for implementing a settimeout function in a VUEJS script

I'm currently working on my first Vue.js application and I'm facing an issue with the initial data upload in the script. After modifying the data received from a database call, I encounter an error during the page's initial load which resolv ...

What is the best approach for nesting Vue Components and passing additional elements as their children?

When working in React, my approach would look like this: //ParentComponent.js (<div> {this.props.children} </div>) //ChildComponent.js (<div> I'm the child! </div>) //App.js import ParentComponent import ChildComponent ...

React Native formInput Component with Underline Decoration

Utilizing the FormInput element in React Native Elements, I have observed a line underneath each FormInput component. Interestingly, one line appears fainter than the other. This is how the form looks: <View style={styles.container}> ...

Choosing only those elements that are not children of parents with a specific class by utilizing the `.not()` method

I am attempting to target all elements having the class .select that are nested somewhere within the DOM tree. The only condition is that these elements should not have any ancestors with the class .forbidden. This means it will not detect any elements ...

Pass multiple variables from a Laravel controller to a Vue component

Let's consider a Vue component as shown below: export default { created() { axios.get("a url").then(res => { console.log(res.data); }); } }; Next, Axios sends a request to the following function in a Laravel co ...

Guide on importing TypeScript types into Vuetify 3

Exploring the use of the ValidationRule type from the Vuetify library (check out the docs and source code), I'm facing difficulties importing it into my Vue.js component. I have attempted to import the type in different ways, such as: import type { V ...

An unexpected error has occurred: Uncaught promise rejection with the following message: Assertion error detected - The type provided is not a ComponentType and does not contain the 'ɵcmp' property

I encountered an issue in my Angular app where a link was directing to an external URL. When clicking on that link, I received the following error message in the console: ERROR Error: Uncaught (in promise): Error: ASSERTION ERROR: Type passed in is not Co ...

Oops! The Route post function is missing some necessary callback functions, resulting in an undefined object error

I need to verify if a user has admin privileges. Every time I try calling the verifyAdminUser function from my router, I encounter the following error: Error: Route.post() requires callback functions but got a [object Undefined] at Route.(anonymous func ...