Home > Blockchain >  Issue with return value of functions that accept different object interfaces?
Issue with return value of functions that accept different object interfaces?

Time:12-20

Building a command line blackjack app with Node and Typescript, but I'm new to Typescript. I have interfaces set up for player and dealer objects and multiple functions that would ideally be able to accept either interface type and return an updated version of whichever type was passed in. Having issues with the returned type not lining up with the original object. I get the error "Type 'Dealer | Players' is not assignable to type 'Players'. Property 'bank' is missing in type 'Dealer' but required in type 'Players'

interface Dealer {
    hand: string[];
    handValues: number[];
    sum: number;
}

interface Players extends Dealer  {
    bank: number;
} 

let player1: Players = {
    hand: ['Ace','5','Ace'],
    handValues: [11, 5,11],
    sum: 27,
    bank: 900,
}

//changes the last instance of ace from 11 to 1 as long as the players sum is > 21
const alterAceValue = (player: Players | Dealer): Players | Dealer => {
    if (player.hand.includes('Ace')) {
        while (player.sum > 21) {
            let lastIndex = player.handValues.lastIndexOf(11);
            player.handValues[lastIndex] = 1
            player.sum = player.handValues.reduce((p, c) => p   c)
            if (!player.handValues.includes(11)) break;
        }
    }
return player
}

player1 = alterAceValue(player1)

I've tried type narrowing but it still doesn't know what type to return, and the function is not generic enough for a generic function. Setting up different functions for dealer and player interfaces solves the problem, but seems like bad practice to me.

CodePudding user response:

That's pretty much exactly what generic functions are for, actually. From the generic function docs (emphasis mine): "It’s common to write a function where the types of the input relate to the type of the output, or where the types of two inputs are related in some way."

You could add the type parameter <T extends Dealer> and set the player parameter's type and return type both to T.

  • Related