0

I am using typescript in a react project.

I am getting the following error.

Argument of type '{ teams: { home: { name: string; }; away: { name: string; }; }[]' is not assignable to parameter of type 'Fixtures[] | (() => Fixture[])'.

My type definitions and use in a react component are below.

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',
    },
];

I am then using this in my React component like below but

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

Can anyone see what I am doing wrong? I can't see where it is inferring it to be a string when I have said it is a Team.

3 Answers 3

1

The problem is not related to react, its related to how Typescript infers string literal types. Typescript will not infer string literal types unless it has a reason to do so.

In this case initialFixtures is untyped. So typescript has no reason to infer name as 'Liverpool' | 'Man Utd' so it infers it as string. When you later try to assign initialFixtures with its inferred type to Fixture[] the assignment fails (since string is not assignable to 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[]'.

The simple solution is to type initialFixtures and not ask the compiler to infer anything and just check the object literal):

const initialFixtures: Fixtures[]= [
    {
        teams: {
            home: {
                name: 'Liverpool',
            },
            away: {
                name: 'Man Utd',
            },
        },
        winner: 'Liverpool',
    },
];
let o: Fixtures[] = initialFixtures; //ok
Sign up to request clarification or add additional context in comments.

1 Comment

that is the solution :-D
0

For one thing, the shape of your data isn't matching up:

Notice you are using 'term' instead of 'away' in your initialFixtures array, and then 'away' instead of 'name'. So you shapes are not matching up. It may help to declare your initialFixtures const as a Fixtures[] as typescript will probably not implicitly realise that.

It looks like useState is a polymorphic function that takes an array of the assigned type Fixtures or a callback that returns the Fixtures[] type.

So as far as I can tell:

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

Should be

away: {
  name: 'Man Utd'
}

1 Comment

apologies, I amended the question a bit to use different variable names. Updated now
0

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

Reason is typescript thinks that your structure should be:

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

Alternatively you could keep the team type the same but change the Fixtures type to:

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

Keep in mind that winner will be an object of {name: 'Teamname'} Not a string of the team name

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.