解決Vue3 Typescript中類型上不存在的屬性問題
P粉336536706
P粉336536706 2024-03-25 18:27:18
0
1
765

我正在嘗試用來自 API 的線索填充元件。我有一個 LeadService 檔案以及我的 vue 範本檔案。我遇到的問題是,我在模板檔案上使用非同步調用,該調用有效,但是當我去計算值時,它會拋出 property does not exit on type 錯誤。它實際上有效,您可以看到錯誤訊息後面的正確組件。我不知道如何讓錯誤消失。

這裡是服務類別LeadService.ts

import ApiService from "@/core/services/ApiService";

interface Lead {
  id: string;
  first_name: string;
  last_name: string;
  lead_form_name: string;
  email: string;
  campaign: string;
  timestamp: number;
  mobile_number: string;
  message: string;
  medium: string;
  city: string;
  state: string;
  leadType: string;
  quality: string;
  source: string;
  call_link: string;
  company: string;
  country: string;
}

export default class LeadService {

  getLeads() {

    const accountInfo = JSON.parse(localStorage.getItem('accountInfo') || '{}');

    ApiService.setHeader();

    return ApiService.query("/leads", {params: {client_id : accountInfo.client_id}})
      .then(({ data }) => {
        let leadData: Lead[] = data['Items'];
        return leadData;
      })
      .catch(({ response }) => {
        return response;
      });

  }
}

這是我的 vue 範本 Leads.vue

<template>
  <!--begin::Leads-->
  <div class="row gy-5 g-xl-8 mb-8">
    <div class="col-xxl-12">
      <LeadTracker
        :lead-data="leadData"
        :updateQuality="updateQuality"
        :key="componentKey"
      />
    </div>
  </div>

  <div class="row gy-5 gx-xl-8 mb-8">
    <div class="col-xxl-8">
      <LeadMethods
        chart-height="500"
        :method-data="getLeadMethods"
      ></LeadMethods>
    </div>
  </div>
  <!--end::Leads-->
</template>

<script lang="ts">
import { defineComponent, onMounted } from "vue";
import { setCurrentPageTitle } from "@/core/helpers/breadcrumb";
import LeadMethods from "@/components/leads/methods/LeadMethods.vue";
import LeadTracker from "@/components/leads/tracker/LeadTracker.vue";
import LeadService from "@/core/services/LeadService";
import ApiService from "@/core/services/ApiService";

export default defineComponent({
  name: "leads",
  components: {
    LeadMethods,
    LeadTracker,
  },
  data() {
    return {
      leadData: {},
    }
  },
  beforeMount: async function() {
    this.leadData = await new LeadService().getLeads()
  },
  setup() {
    onMounted(() => {
      setCurrentPageTitle("Lead Activity");
    });

    const sourceThreshold = 5;

    return {
      sourceThreshold,
      componentKey: 0
    };
  },
  computed: {
    getLeadMethods(): object {
      const leadMethods: Array<object> = [];
      const totalLeads = this.leadData.length;

      console.log('called getLeadMethods check this.leadData', this.leadData);

      // Get the total number of Paid Media leads
      const totalPaid = this.leadData.filter(
        lead => lead.medium == "paid_media"
      ).length;

      // Get the total number of Calls
      const totalCall = this.leadData.filter(lead => lead.leadType == "call")
        .length;

      // Separate form leads from the rest
      const formData = this.leadData.filter(lead => lead.leadType == "form");

      // Make array for form names
      const formTypes: Array<string> = [];
      this.leadData.filter(lead => {
        if (!formTypes.includes(lead.lead_form_name))
          formTypes.push(lead.lead_form_name);
      });

      // Create objects for each form by name, push to leadMethods
      formTypes.filter(type => {
        let totalFormLeads = 1;
        formData.filter(form => {
          if (form.lead_form_name == type) totalFormLeads++;
        });
        const formMethod = {
          name: type,
          description: "Lorem ipsum dolor sit amet, consectetur.",
          total: totalFormLeads,
          percent: Math.round((totalFormLeads / totalLeads) * 100)
        };
        leadMethods.push(formMethod);
      });

      const callTracking = {
        name: "Location Based Call-Tracking",
        description: "Lorem ipsum dolor sit amet, consectetur.",
        total: totalCall,
        percent: Math.round((totalCall / totalLeads) * 100)
      };
      const paidSearch = {
        name: "Paid Search",
        description: "Lorem ipsum dolor sit amet, consectetur.",
        total: totalPaid,
        percent: Math.round((totalPaid / totalLeads) * 100)
      };

      leadMethods.push(callTracking, paidSearch);

      return leadMethods;
    }
  }
});
</script>

問題始於我的計算函數,我開始過濾 this.LeadData## 基本上每個過濾器都會拋出 Property does not exit on type 錯誤,但它們確實存在。

要注意的是,當 this.leadData 被設定時,它是一個代理。 任何幫助將不勝感激,我想知道是否可以抑制錯誤,儘管我不喜歡這個解決方案。

例如,在計算方法中的第一個篩選器中

// Get the total number of Paid Media leads
      const totalPaid = this.leadData.filter(
        lead => lead.medium == "paid_media"
      ).length;

mediumleadData 的一個屬性,我實際上可以控制台記錄它並且它工作得很好,但它仍然總是拋出property does not exit on type

P粉336536706
P粉336536706

全部回覆(1)
P粉111627787

leadData 的型別是從 data() 中的宣告推斷出來的。它被初始化為 {},這意味著它的類型是一個不可變的空物件(並且不能附加任何屬性)。但是,leadData 最終被指派了 LeadService().getLeads() 的回傳值,所以它的型別其實應該是 Lead 物件的陣列。

要正確輸入 leadData,請使用 Lead[] 的型別斷言:

export default defineComponent({
  data() {
    return {
      //leadData: {}, ❌
      leadData: [] as Lead[], ✅
    }
  }
})
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板