代码之家  ›  专栏  ›  技术社区  ›  Karol

将javascript箭头函数更改为typesctipt

  •  0
  • Karol  · 技术社区  · 4 年前

    格蕾廷斯。

    所以我试着打字。 我所基于的初始代码是基于javascript的

    const PokemonTable = () => {
      const pokemon = useStore((state) => state.pokemon);
      const filter = useStore((state) => state.filter);
    
      return (
        <table width="100%">
          <tbody>
            {pokemon
              .filter(({ name: { english } }) =>
                english.toLowerCase().includes(filter.toLowerCase())
              )
              .map(({ id, name: { english }, type }) => (
                <tr key={id}>
                  <td>{english}</td>
                  <td>{type.join(", ")}</td>
                </tr>
              ))}
          </tbody>
        </table>
      );
    };
    

    当我把它改成打字稿时,它会抛出这些错误

    Error

    我试图创建一个界面,将道具传递给它

    //interfaz de pokemon table
    interface PkTableProps{
      id:number,
      name:Array<String>,
      type:Array<String>,
    }
    

    然后我应用了箭头函数

    // pokemon table
    
    const PokemonTable = (props : PkTableProps) => {
      const pokemon = useStore((state) => state.pokemon);
      const filter = useStore((state) => state.filter);
    
      return (
        <table width="100%">
          <tbody>
            {pokemon
              .filter(({ props.name : { english } }) =>
                english.toLowerCase().includes(filter.toLowerCase())
              )
              .map(({ id, props.name: { english }, props.type }) => (
                <tr key={props.id}>
                  <td>{english}</td>
                  <td>{props.type.join(", ")}</td>
                </tr>
              ))}
          </tbody>
        </table>
      );
    };
    

    我发现了这些新的语法错误

    Error

    注:

    在线 <td>{english}</td> 在箭头函数的表上。我这样做是因为我试图用英语选择每个口袋妖怪的名字。这意味着我想要它 key

    这是我使用的口袋妖怪阵列的结构
    https://gist.githubusercontent.com/jherr/23ae3f96cf5ac341c98cd9aa164d2fe3/raw/0658aeff401d196dece7ec6fe6c726c6adc1cc00/gistfile1.txt

    这是完整的代码

    import React from "react";
    import "./App.css";
    import create from "zustand";
    // import { mountStoreDevtool } from 'simple-zustand-devtools';
    
    const POKEMON_URL =
      "https://gist.githubusercontent.com/jherr/23ae3f96cf5ac341c98cd9aa164d2fe3/raw/f8d792f5b2cf97eaaf9f0c2119918f333e348823/pokemon.json";
    
    // definir el tipo de mi store
    type State = {
      filter: string;
      pokemon: Array<string>;
      setFilter: (filter: string) => void;
      setPokemon: (pokemon: Array<string>) => void;
    };
    
    //interfaz de pokemon table
    interface PkTableProps{
      id:number,
      name:Array<String>,
      type:Array<String>,
    }
    
    
    //tienda de estados
    const useStore = create<State>((set) => ({
      // set initial values here
      filter: "",
      pokemon: [],
    
      setFilter: (filter: string) =>
        set((state) => ({
          ...state,
          filter,
        })),
    
      setPokemon: (pokemon: Array<string>) =>
        set((state) => ({
          ...state,
          pokemon,
        })),
    }));
    
    // if (process.env.NODE_ENV === 'development') {
    //   mountStoreDevtool('Store', store);
    // }
    
    //  input
    const FilterInput = () => {
      const filter = useStore((state) => state.filter);
      const setFilter = useStore((state) => state.setFilter);
      return (
        <input value={filter} onChange={(evt) => setFilter(evt.target.value)} />
      );
    };
    
    // pokemon table
    
    const PokemonTable = (props : PkTableProps) => {
      const pokemon = useStore((state) => state.pokemon);
      const filter = useStore((state) => state.filter);
    
      return (
        <table width="100%">
          <tbody>
            {pokemon
              .filter(({ props.name : { english } }) =>
                english.toLowerCase().includes(filter.toLowerCase())
              )
              .map(({ id, props.name: { english }, props.type }) => (
                <tr key={props.id}>
                  <td>{english}</td>
                  <td>{props.type.join(", ")}</td>
                </tr>
              ))}
          </tbody>
        </table>
      );
    };
    
    
    function App()  {
      const setPokemon = useStore((state) => state.setPokemon);
      
    
      //lifecycle hook every time the component renders
    
      React.useEffect(() => {
        fetch(POKEMON_URL)
          .then((resp) => resp.json())
          .then((pokemon) => setPokemon(pokemon));
      });
    
      return (
        <div className="App">
          <div>
            <FilterInput />
          
          </div>
          <h1>List of Pokemons</h1>
          <PokemonTable />
          {/* mostrar el resultado de filter */}
          {/* {filter}   */}
          {/* mostar lo que el contenido del array de la url */}
          {/* {JSON.stringify(pokemon)} */}
        </div>
      );
    }
    
    export default App;
    
    0 回复  |  直到 4 年前
        1
  •  0
  •   Linda Paiste    3 年前
    type State = {
      filter: string;
      pokemon: Array<string>;
      setFilter: (filter: string) => void;
      setPokemon: (pokemon: Array<string>) => void;
    };
    

    这种类型表示 pokemon 你商店的财产是一系列 String (应该是小写 string 相反)。

    pokemon.filter(({ name: { english } }) =>
    

    此函数处理 宝可梦 数组作为一个对象 name 财产。这个 名称 它本身就是一个 object 拥有房产 english 这是一个 一串 .

    这是两种不同且不兼容的类型,这就是为什么会出现错误。


    你需要弄清楚哪个是正确的,哪个是错误的。链接 .txt 文件对此有所帮助。Pokemon对象看起来像这样:

    {
      id: 1,
      name: {
        english: "Bulbasaur",
        japanese: "フシギダネ",
        chinese: "妙蛙种子",
        french: "Bulbizarre"
      },
      type: ["Grass", "Poison"],
      base: {
        HP: 45,
        Attack: 49,
        Defense: 49,
        "Sp. Attack": 65,
        "Sp. Defense": 65,
        Speed: 45
      }
    };
    

    所以我们可以看到 名称 property是一个具有属性的对象 英语 -- Array<string> .

    这取决于你想对自己的类型有多具体。你可以描述一下 名称 财产作为

    type Name = Record<string, string>
    

    该对象的键和值都是 一串 这意味着任何 一串 可以用作密钥。所以你可能想更具体地说,这是一个看起来像这样的对象:

    type Name = {
      english: string;
      japanese: string;
      chinese: string;
      french: string;
    }
    

    如果你试图访问无效的密钥,这会给你一个错误,比如 name.spanish .


    这个 宝可梦 您的财产 State 是一个 Array 但它不是一个数组 一串 --这是一系列口袋妖怪物品。我们需要定义a的类型 Pokemon 基于您的数据文件。

    type Pokemon = {
      id: number;
      name: {
        english: string;
        japanese: string;
        chinese: string;
        french: string;
      };
      type: Array<string>;
      base: {
        HP: number;
        Attack: number;
        Defense: number;
        "Sp. Attack": number;
        "Sp. Defense": number;
        Speed: number;
      }
    }
    

    你的 国家 类型可以使用此 宝可梦 类型:

    type State = {
      filter: string;
      pokemon: Array<Pokemon>;
      setFilter: (filter: string) => void;
      setPokemon: (pokemon: Array<Pokemon>) => void;
    };
    

    由于您使用的是泛型 <State> 在你的 create 函数中,您可以通过删除参数上的类型来修复弹出的错误。它们将从您的 国家 类型。

    const useStore = create<State>((set) => ({
      // set initial values here
      filter: "",
      pokemon: [],
    
      setFilter: (filter) =>
        set((state) => ({
          ...state,
          filter,
        })),
    
      setPokemon: (pokemon) =>
        set((state) => ({
          ...state,
          pokemon,
        })),
    }));
    

    在您的第一个版本中 PokemonTable 没有拿任何道具。这个更接近正确。因此,您可以删除您的 PkTableProps 界面。你需要的所有数据都来自商店,而不是道具。

    现在 国家 有正确的类型,你的首字母 口袋妖怪桌 组件工作!

    const PokemonTable = () => {
      const pokemon = useStore((state) => state.pokemon);
      const filter = useStore((state) => state.filter);
    
      return (
        <table width="100%">
          <tbody>
            {pokemon
              .filter(({ name: { english } }) =>
                english.toLowerCase().includes(filter.toLowerCase())
              )
              .map(({ id, name: { english }, type }) => (
                <tr key={id}>
                  <td>{english}</td>
                  <td>{type.join(", ")}</td>
                </tr>
              ))}
          </tbody>
        </table>
      );
    };
    

    嵌套破坏 .filter(({ name: { english } }) 可能很难阅读。如果你这样写,可能会更容易理解。

    const PokemonTable = () => {
      const pokemonArray = useStore((state) => state.pokemon);
      const filter = useStore((state) => state.filter);
    
      return (
        <table width="100%">
          <tbody>
          {pokemonArray
              .filter(pokemon =>
                pokemon.name.english.toLowerCase().includes(filter.toLowerCase())
              )
              .map((pokemon) => (
                <tr key={pokemon.id}>
                  <td>{pokemon.name.english}</td>
                  <td>{pokemon.type.join(", ")}</td>
                </tr>
              ))}
          </tbody>
        </table>
      );
    };
    

    最后一件事——你只需要 useEffect 它获取口袋妖怪数据并运行一次。你可以给它一个空的依赖数组 [] 或一个依赖数组 [setPokemon] .

    Working CodeSandbox Link