Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

187
Views
Question about how to treat the "this" keyword in TypeScript. (Vue project)

I'm fairly new to TypeScript and I'm running into an issue. I have a .ts I'm using to store some helper functions. These functions are called via .call so the proper this is referenced. In that file, each this gives the following two errors:

'this' implicitly has type 'any' because it does not have a type annotation.

An outer value of 'this' is shadowed by this container.

Relevant section of the component file:

<script lang="ts">
import { defineComponent } from "vue";
import { deleteTodo, getId, setEditId, toggleDone } from "./App.helpers";
import EditTodoDialog from "./components/EditTodoDialog.vue";
import TodoForm from "./components/TodoForm.vue";
import TodoTable from "./components/TodoTable.vue";

export default defineComponent({
  components: { EditTodoDialog, TodoForm, TodoTable },
  data() {
    return {
      addTodoInputValue: "" as string,
      editTodoId: "" as string,
      editTodoInputValue: "" as string,
      todoArr: [] as Array,
    };
  },
  methods: {
    addTodo() {
      if (this.addTodoInputValue) {
        const id = getId();
        const newTodo = {
          handleDelete: () => deleteTodo.call(this, id),
          handleSetEditId: () => setEditId.call(this, id),
          handleToggleDone: () => toggleDone.call(this, id),
          id,
          isDone: false,
          task: this.addTodoInputValue,
        };
        this.todoArr.push(newTodo);
        this.addTodoInputValue = "";
      }
    },
    closeDialog() {
      this.editTodoId = "";
    },
    updateTodo() {
      if (this.editTodoInputValue) {
        const targetIndex = this.todoArr.findIndex(
          ({ id }) => id === this.editTodoId
        );
        this.todoArr[targetIndex].task = this.editTodoInputValue;
        this.editTodoId = "";
        this.editTodoInputValue = "";
      }
    },
  },
  name: "App",
});
</script>

Helpers file:

export function deleteTodo(targetId: string) {
  const targetIndex = this.todoArr.findIndex(
    ({ id }: { id: string }) => id === targetId
  );
  this.todoArr.splice(targetIndex, 1);
}

export function getId() {
  return `${getRandomNumStr()}-${getRandomNumStr()}`;
}

export function getRandomNumStr() {
  return Math.random().toString().slice(2);
}

export function setEditId(id: string) {
  this.editTodoId = id;
}

export function toggleDone(targetId: string) {
  const targetIndex = this.todoArr.findIndex(
    ({ id }: { id: string }) => id === targetId
  );
  const targetTodo = this.todoArr[targetIndex];
  targetTodo.isDone = !targetTodo.isDone;
}

about 4 years ago · Juan Pablo Isaza
2 answers
Answer question

0

Your helpers class is not declaring the functions on any object, so when you call deleteTodo the only this in scope is the current function, which means that this.todoArr doesn't exist as it isn't declared in the function. Typescript is more object oriented than regular javascript and it doesn't understand throwing functions around in quite the same way.

You might try something like this:

export class Helpers {
  public function deleteTodo(todoArr: Array<ToDo>, targetId: string): Array<ToDo> {
    const targetIndex = todoArr.findIndex(
      ({ id }: { id: string }) => id === targetId
    );
    todoArr.splice(targetIndex, 1);
    return todoArr;
  }

  // And so on
}

Then you would call it with this.todoArr = Helpers.deleteTodo(this.todoArr, 'banana') and so on.

To me that feels a little clunky- if you're going to want to call deleteTodo from a few different places, then I would think about how you structure things. I would probably have some kind of TodoService that handles deletion, updates and so on and then call that from different components so there is a single point of responsibility. Alternatively you could also have a TodoHandler class that includes those methods and have the types that need it inherit from it, so those methods and collections are automatically available. I use Typescript a lot but I haven't worked with Vue so I can't say what would be the most idiomatic approach in that respect.

Having functions to generate Ids and other commonly used simple functions in helper classes works great, but altering your data model is more structurally significant and probably belongs in its own place.

about 4 years ago · Juan Pablo Isaza Report

0

For anyone in a similar situation looking to reference some code - I got things in pretty good shape, here's the repo: https://github.com/colebillys19/vue-todo

In a nutshell, I created a TodoList class that handles a lot of the main logic. As glenatron mentioned, TypeScript likes more of an OOP approach compared to standard JS.

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!