理解vue + TS中的FetchAPI

问题描述 投票:0回答:1

我正在开发一个简单的笔记应用程序。我需要从服务器获取数据然后渲染它。我有一堆现成的组件和工作后端,但在获取数据方面有点困难。当我尝试构建它时,会出现错误。还想问 ts 是否会正确输入响应,因为有一些额外的字段。

App.vue:

<script setup lang="ts">
import Form from "./components/Form.vue";
import NoteItem from "./components/NoteItem.vue";

type Note = {
    title: string;
    content: string;
}

let loaded = false;
let noNotes = false;
const telegramId = "test"
const notes: Promise<Note[]> = fetch(`http://localhost:3000/notes/${telegramId}`)
    .then((res) => {
      if (res.status === 404) {
        noNotes = true;
      }

      return res.json() as Note[];
    })
    .then(() => loaded = true)
    .catch((err) => console.log(err));
</script>

<template>
  <div class="flex flex-col justify-center items-center justify-items-center h-screen space-x-4 gap-0">
    <h1 class="font-bold h-max text-6xl font-serif underline decoration-sky-500">Notes</h1>
    <Form/>
    <div class="grid grid-cols-3 w-1/3 mt-8 gap-4">
      <div v-if="loaded">
        <div v-for="note in notes">
          <NoteItem :title="note.title" :content="note.content"/>
        </div>
      </div>
      <div v-else>
        <h2 v-if="noNotes"></h2>
        <h2 v-else>Fetching...</h2>
      </div>
    </div>
  </div>
</template>

<style scoped>
</style>

响应示例:

[
    {
        "ID": 1,
        "CreatedAt": "2024-10-16T18:17:25.141109Z",
        "UpdatedAt": "2024-10-16T18:17:25.141109Z",
        "DeletedAt": null,
        "TelegramId": "test",
        "Title": "Test3",
        "Content": "Test3"
    }
]

错误:

src/App.vue:13:7 - error TS2322: Type 'Promise<boolean | void>' is not assignable to type 'Promise<Note[]>'.
  Type 'boolean | void' is not assignable to type 'Note[]'.
    Type 'boolean' is not assignable to type 'Note[]'.

13 const notes: Promise<Note[]> = fetch(`http://localhost:3000/notes/${telegramId}`)
         ~~~~~

src/App.vue:19:14 - error TS2352: Conversion of type 'Promise<any>' to type 'Note[]' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
  Type 'Promise<any>' is missing the following properties from type 'Note[]': length, pop, push, concat, and 28 more.

19       return res.json() as Note[];
                ~~~~~~~~~~~~~~~~~~~~

src/App.vue:32:34 - error TS2339: Property 'title' does not exist on type 'string | (<TResult1 = Note[], TResult2 = never>(onfulfilled?: ((value: Note[]) => TResult1 | PromiseLike<TResult1>) | null | undefined, onrejected?: ((reason: any) => TResult2 | PromiseLike<...>) | null | undefined) => Promise<...>) | (<TResult = never>(onrejected?: ((reason: any) => TResult | PromiseLike<...>) | .....'.
  Property 'title' does not exist on type 'string'.

32           <NoteItem :title="note.title" :content="note.content"/>
                                    ~~~~~

src/App.vue:32:56 - error TS2339: Property 'content' does not exist on type 'string | (<TResult1 = Note[], TResult2 = never>(onfulfilled?: ((value: Note[]) => TResult1 | PromiseLike<TResult1>) | null | undefined, onrejected?: ((reason: any) => TResult2 | PromiseLike<...>) | null | undefined) => Promise<...>) | (<TResult = never>(onrejected?: ((reason: any) => TResult | PromiseLike<...>) | .....'.
  Property 'content' does not exist on type 'string'.

32           <NoteItem :title="note.title" :content="note.content"/>
typescript vue.js fetch-api
1个回答
0
投票

const fetchNotes = async () => {
  try {
    const response = await fetch(`http://localhost:3000/notes/${telegramId}`);
    if (response.status === 404) {
      noNotes.value = true;
      loaded.value = true;
      return;
    }
    const data = await response.json();
    const notes: Note[] = data.map((item: any) => ({
      title: item.Title,
      content: item.Content
    }));
    notes.value = notes;
    loaded.value = true;
  } catch (err) {
    console.log(err);
  }
};

this is right

© www.soinside.com 2019 - 2024. All rights reserved.