I am trying to copy a component from one of my old vue projects that only uses JS into a TS/Vue Project and came across a few hurdles.
<script lang="ts">
import { computed, ref } from "vue";
import { defineComponent } from 'vue'
export default defineComponent ({
setup() {
const todo = ref("");
const todos = ref([]);
let id = 0;
const numberOfCompletedTodos = computed(
() => todos.value.filter((todo) => todo.completed).length
);
function addTodo() {
todos.value.push({
id: id,
title: todo.value.trim(),
completed: false,
});
todo.value = "";
id++;
}
function removeTodo(index) {
todos.value.splice(index, 1);
}
...
...
...
</script>
Because of the ref([]) I am getting the following errors:
- Argument of type '{ id: number; title: string; completed: boolean; }' is not
assignable to parameter of type 'never'.ts(2345)
- Property 'completed' does not exist on type 'never'.
- Parameter 'index' implicitly has an 'any' type.
>Solution :
The ref function is generic – it can infer the type of the value you want to store in the returned reference. Since you pass an empty array, the type that is inferred is never[], which means an array that will never have any elements. This is obviously not what you want. You could initialize the ref with an array that has a Todo, but that’s not ideal.
In this case, you need to tell TypeScript that you intend to store Todos in this array. You can do this by passing a type parameter to the ref function. Define a type or an interface for Todo and pass it like this:
type Todo = {
id: number;
title: string;
completed: boolean;
}
const todos = ref<Todo[]>([]);
You can also do this inline:
const todos = ref<{ id: number; title: string; completed: boolean }[]>([]);