簡體   English   中英

Reactjs Typerscript:類型“ never”上不存在屬性“ toLowerCase”

[英]Reactjs Typerscript: Property 'toLowerCase' does not exist on type 'never'

我試圖在帶有tsx的reactjs中過濾具有多個鍵值的數據。 Cards.tsx是父組件,而ShipmentCard.tsx是子組件。 我收到Property 'toLowerCase' does not exist on type 'never'錯誤的Property 'toLowerCase' does not exist on type 'never' 我只想根據搜索條件返回相關對象。 誰能告訴我我在哪里犯錯了?

Cards.tsx

 class Cards extends Component { state = { card: [], filter: "" }; componentDidMount() { this.loadShipmentList(); } handleChange = (event: any) => { this.setState({ filter: event.target.value }); }; loadShipmentList() { fetch("http://localhost:3001/shipments") .then(response => response.json()) .then(data => this.setState({ card: data })); } render() { const { card, filter } = this.state; const lowercasedFilter = filter.toLowerCase(); const filteredData = this.state.card.filter(item => { return Object.keys(item).some(key => item[key].toLowerCase().includes(lowercasedFilter) ); }); return ( <Card className="Search-Bar"> <CardContent> <Grid container spacing={3}> <TextField label="Search" onChange={this.handleChange} /> </Grid> </CardContent> </Card> <Grid container spacing={3}> {filteredData.map((card: any) => ( <Grid item xs={12}> <ShipmentCard key={card.id} value={card} /> </Grid> ))} </Grid> ); } } export default Cards; 
db.json

 { "shipments": [ { "id": "123", "name": "Heromisha", "total": "1000", "status": "ACTIVE", "userId": "E222" }, { "id": "456", "name": "Honda", "total": "3000", "status": "ACTIVE", "userId": "E111" } ] } 

Component是具有兩個類型參數的通用接口:道具的類型和狀態的類型。 您的組件似乎沒有道具,因此您只能將object{}用於道具接口,但是您確實有狀態,因此您需要說明該狀態的形狀

interface Card {
  id:     string;
  name:   string;
  total:  string;
  status: string;
  userId: string;
}
interface CardsState {
  card:   Card[];
  filter: string;
}
class Cards extends Component<object,CardsState> {
  state: CardsState = {
    card: [],
    filter: ""
  };
  // ...
}

另外,我懷疑您接下來會遇到的兩個問題是:

  1. 您沒有檢查是否成功fetch 您並不孤單,這是一個非常常見的錯誤(很常見,我在貧乏的小博客上寫下了它 )。 您需要在fetch調用中添加一張支票:

     fetch("http://localhost:3001/shipments") .then(response => { if (!response.ok) { throw new Error("HTTP error " + response.status); } return response.json(); }) // ... 
  2. 您不處理來自fetch錯誤。 loadShipmentList應該返回承諾鏈(然后componentDidMount及其使用的其他位置將處理錯誤)或自身處理/報告錯誤。

  3. 您正在將card設置為解析JSON的結果。 您的代碼假設card是一個數組,但是JSON的頂層不是數組,它是一個帶有shipments屬性的對象(它是一個數組)。 我懷疑您是想將card (應該是cards ,plural或shipments )設置為返回數據的shipments屬性:

     .then(({shipments}) => this.setState({ card: shipments })); // ^^ ^^ ^^^^^^^^^ 

可能還有其他問題,但是上面的主要答案應該解決never問題,希望這些進一步的提示有所幫助。


在評論中,您說過,當您給card指定類型時,此代碼會導致錯誤:

const filteredData = this.state.card.filter(item => {
  return Object.keys(item).some(key =>
    item[key].toLowerCase().includes(lowercasedFilter)
  );
});

如果您希望JSON中的數據形狀可變,則可以將card聲明為any[] (或也許Record<string,string>[] ),然后該動態代碼將起作用。 但僅當您希望組件由JSON驅動時。 否則,更新代碼以使用typesafe屬性名稱:

const filteredData = this.state.card.filter(({id, name, total, status, userId}) =>
  `${id}\t${name}\t${total}\t${status}\t${userId}`.toLowerCase().includes(lowercasedFilter)
);

編譯器不是state.card [...]的真實類型,因為它被聲明為數組。 最簡單的方法是將其聲明為any []

  state = {
    card: [] as any[],
    filter: ""
  };

或顯式描述數據類型

interface Card {
    "id": string,
    "name": string,
    "total": string,
    "status": string,
    "userId": string
}
...
      state = {
        card: [] as Card[],
        filter: ""
      };

或通過對象示例

const cardSample = {
      "id": "123",
      "name": "Heromisha",
      "total": "1000",
      "status": "ACTIVE",
      "userId": "E222"
  };

type Card = typeof cardSample;

    ...
          state = {
            card: [] as Card[],
            filter: ""
          };

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM