0

EDIT: VLAZ's link's accepted answer was helpful - Types in object destructuring


None of the other questions I read before making this post applied to what I'm looking for, I think.

For this example I'm using axios to make a GET request to jsonplaceholder.

const url = 'https://jsonplaceholder.typicode.com/todos/1';
axios.get(url).then((res) => {})

The res object has a data property, which I want to destructure and call it todo

Without typescript, I would have this:

axios.get(url).then((res) => {
  const { data: todo } = res;
  const ID = todo.id;
  const title = todo.title;
  const completed = todo.completed;
  console.log(ID, title, completed)
});

It works, but I want to make an interface for the todo variable:

interface Todo {
  id: number;
  title: string;
  completed: boolean;
}

How do I cast the todo variable to this interface so that I have autocomplete on my editor?

I tried this:

const { data: todo }: Todo = res;

But the compiler complains: Property 'data' does not exist on type 'Todo'

I'm guessing I'm trying to cast the whole res object to the interface Todo, but I don't know how to keep the destructuring+renaming of the data property wile casting it to an interface

C. Rib
  • 340
  • 3
  • 19
  • Agreeing with VLAZ, but OP is there a reason you need to destructure rather than just setting `const data: Todo = res.data`? Are you destructuring other variables you haven't shown us here? – Jeff Bowman Jan 11 '22 at 19:08
  • Isn't there any other way of assigning a type to a renamed destrucured property without basically repeating myself? From @VLAZ's suggestion, I could do `const {data: newTodo} : {data: Todo} = res` but wouldn't I just be repeating myself, thus missing the point of a destructure in the first place? – C. Rib Jan 11 '22 at 19:29
  • @JeffBowman just an easy to explain example, in this case res.data would make sense but not really in a real world case scenario where destructuring would make sense. – C. Rib Jan 11 '22 at 19:30
  • 1
    @C.Rib what if you had `const { a: foo, b: bar }` - how would you "simply" give both a type in that case?\ – VLAZ Jan 11 '22 at 19:31
  • @VLAZ would something like `interface AB { a: IA; b: IB }` work? Otherwise, `const { a: foo, b: bar } : {a: IA, b: IB }` ... I see your point now – C. Rib Jan 11 '22 at 19:33
  • 1
    Then you've come up with the same solution you said isn't simple. `const { a: foo, b: bar } : AB` is the same as `const { a: foo, b: bar } : { a: IA, b: IB }` only the type is placed elsewhere. You've still repeated yourself. – VLAZ Jan 11 '22 at 19:35
  • Perfect, you've convinced me. Thanks. Guess sometimes just there isn't a simpler way, not that in this case would make much sense after all. Thanks again. I'll link your link in my post then ask to close it. – C. Rib Jan 11 '22 at 19:36

0 Answers0