I have been exploring the concepts of "type safety" in my project using Vue3, TypeScript, and Axios.
Although it seems straightforward, I can't shake the feeling that I am overlooking something obvious!
To start off, I defined an interface called Book
:
Book.ts
interface Book {
id: string;
userId: string;
title: string;
content: string;
}
export default Book;
In addition, I set up a basic service to fetch JSON data like this:
{
"userId": 1,
"id": 1,
"title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
"body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
},
(Please note: The JSON uses body
instead of content
as specified in the interface)
DataService.ts
import axios, { AxiosResponse } from "axios";
import Book from "@/interfaces/Book";
class DataService {
async FetchBooks(): Promise<Book[]> {
let response: Book[] = [
{ id: "1", userId: "someone", title: "A title", content: "Some content" }
];
try {
const val = await axios.get<Book[]>(
`https://jsonplaceholder.typicode.com/posts`
);
if (val.data && val.status === 200) {
response = val.data;
}
} catch (error) {
console.log(error);
}
return response;
}
}
export default new DataService();
My primary concern is why the response still includes "body" even though it's not part of the Book
interface. I assumed it would be omitted since I specified the type as Book
in the axios get request.
Another question arises regarding why I can use {{ book.body }}
in the template below, considering that I'm treating the response as a Book
object without defining "body" in the interface.
Book.vue
<template>
<div v-for="book in books" :key="book.id">
<div class="mb-2">
{{ book.body }}
</div>
</div>
</template>
<script lang="ts">
import { defineComponent } from "vue";
import DataService from "@/services/DataService";
// eslint-disable-next-line no-unused-vars
import Book from "@/interfaces/Book";
export default defineComponent({
async setup() {
let books: Book[] = [];
await DataService.FetchBooks().then(data => (books = data));
return { books };
}
});
</script>