【问题标题】:React typescript is not assignable to parameter of typeReact 打字稿不能分配给类型的参数
【发布时间】:2019-06-16 23:01:30
【问题描述】:

我在 react 项目中使用 typescript。

我收到以下错误。

类型参数 '{ teams: { home: { name: string; };离开: { 名称:字符串; }; }[]' 不可分配给类型参数 '夹具[] | (() => Fixture[])'。

我的类型定义和在反应组件中的使用如下。

type Team = {
    name: 'Liverpool' | 'Man Utd';
};

type Fixtures = {
    teams: {
        home: {
            name: Team;
        },
        away: {
            name: Team;
        },
        winner: Team;
    };
};

const initialFixtures = [
    {
        teams: {
            home: {
                name: 'Liverpool',
            },
            away: {
                name: 'Man Utd',
            },
        },
        winner: 'Liverpool',
    },
];

然后我在我的 React 组件中使用它,如下所示,但是

// Error is in `initial fixtures`
const [fixtures, updateFixtures] = useState<Fixtures[]>(initialFixtures);

谁能看到我做错了什么?当我说它是Team 时,我看不出它在哪里推断它是一个字符串。

【问题讨论】:

    标签: javascript reactjs typescript ecmascript-6 types


    【解决方案1】:

    这个问题与 react 无关,它与 Typescript 如何推断字符串文字类型有关。除非有理由,否则 Typescript 不会推断字符串文字类型。

    在这种情况下,initialFixtures 是无类型的。所以打字稿没有理由将name推断为'Liverpool' | 'Man Utd',所以它推断为string。当您稍后尝试将带有推断类型的initialFixtures 分配给Fixture[] 时,分配失败(因为string 不能分配给Team):

    type Team =  'Liverpool' | 'Man Utd';
    
    type Fixtures = {
        teams: {
            home: {
                name: Team;
            },
            away: {
                name: Team;
            },
        };
        winner: Team;
    };
    
    const initialFixtures= [
        {
            teams: {
                home: {
                    name: 'Liverpool',
                },
                away: {
                    name: 'Man Utd',
                },
            },
            winner: 'Liverpool',
        },
    ];
    let o: Fixtures[] = initialFixtures; // error here 
    // Type '{ teams: { home: { name: string; }; away: { name: string; }; }; winner: string; }[]' is not assignable to type 'Fixtures[]'.
    

    简单的解决方案是输入initialFixtures,而不要求编译器推断任何内容,只检查对象字面量):

    const initialFixtures: Fixtures[]= [
        {
            teams: {
                home: {
                    name: 'Liverpool',
                },
                away: {
                    name: 'Man Utd',
                },
            },
            winner: 'Liverpool',
        },
    ];
    let o: Fixtures[] = initialFixtures; //ok
    

    【讨论】:

    • 这就是解决方案:-D
    【解决方案2】:

    type Team = 'Liverpool' | 'Man Utd';

    原因是 typescript 认为你的结构应该是:

                home: {
                    name: {
                       name: 'Liverpool'
                    }
                },
                away: {
                    name: {
                       name: 'Man Utd'
                    }
                },
    
    

    或者,您可以保持团队类型相同,但将夹具类型更改为:

    type Fixtures = {
        teams: {
            home: Team;
            away: Team;
            winner: Team;
        };
    };
    

    请记住,获胜者将是 {name: 'Teamname'} 的对象,而不是团队名称的字符串

    【讨论】:

      【解决方案3】:

      一方面,您的数据形状不匹配:

      请注意,您在 initialFixtures 数组中使用的是“term”而不是“away”,然后是“away”而不是“name”。所以你的形状不匹配。将您的 initialFixtures const 声明为 Fixtures[] 可能会有所帮助,因为打字稿可能不会隐含地意识到这一点。

      看起来 useState 是一个多态函数,它接受一个指定类型 Fixtures 的数组或一个返回 Fixtures[] 类型的回调。

      据我所知:

      term: {
        away: 'Man Utd',
      }, 
      

      应该是

      away: {
        name: 'Man Utd'
      }
      

      【讨论】:

      • 抱歉,我稍微修改了问题以使用不同的变量名称。现已更新
      猜你喜欢
      • 2021-04-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-26
      • 2021-10-18
      • 1970-01-01
      • 2021-10-11
      • 2021-03-02
      相关资源
      最近更新 更多