0

I'm trying to create a sort function in AssemblyScript but am receiving this error in the function. I'd like the sort function to be re-usable and take in two possible sort parameters. I'm passing in a class that has an index signature but getting this error.

I've read several other questions that didn't help me solve it:

Also, came across this in their Github: https://github.com/AssemblyScript/assemblyscript/issues/1972

Full code here: https://pastebin.com/gXY5PxVn

Summary of code:

export function processPlayers ( allPlayerData: Array<PlayerData> ): Array<PlayerData> {
    let players = sortPlayersByField(allPlayerData);
    ...
};

const sortPlayersByField = function(
    players: Array<PlayerData>,
    field: String = 'fantasy_points',
    secondaryField: String = ''
): Array<PlayerData>{
    const sortFunc = function(
        a: PlayerData,
        b: PlayerData
    ): i32{
        // --- Handle when the field isn't set or has no value
        if(!a[field] && !b[field]){
            return 0;
        }
        if(!a[field]){
            return 1;
        }
        if(!b[field]){
            return -1;
        }
        ...
    }
    players.sort(sortFunc)
    return players;
}

/**
 * Definition for all data for a player that gets returned by the query to get
 * all players in a league for the draft board
 */
class PlayerData {
    [key: String]: any // --- Index signature IS present
    player_id: number
    ...
}

Summary of the errors:

ERROR TS2329: Index signature is missing in type 'assembly/index/PlayerData'.
    :
 40 │ if(!a[field] && !b[field]){
    │     ~
    └─ in assembly/index.ts(40,13)

ERROR TS2329: Index signature is missing in type 'assembly/index/PlayerData'.
    :
 40 │ if(!a[field] && !b[field]){
    │                  ~
    └─ in assembly/index.ts(40,26)

ERROR TS2329: Index signature is missing in type 'assembly/index/PlayerData'.
    :
 43 │ if(!a[field]){
    │     ~
    └─ in assembly/index.ts(43,13)

ERROR TS2329: Index signature is missing in type 'assembly/index/PlayerData'.
    :
 46 │ if(!b[field]){
    │     ~
    └─ in assembly/index.ts(46,13)

I have tried to use an interface and assign it to the class but it results in the same error. I tried using a type like in some of the other questions I looked at but that didn't even work in AssemblyScript, it wouldn't compile while declaring a type. I've tried changing the signature of 'sortFunc' to not the PlayerData type but create a generic object type with the index signature included and that also results in compilation errors. Not sure how to handle this.

############################

Second Example

I ran into another example of this while trying to work around it. This one's a little more clear.

Full code here: https://pastebin.com/zKUCTLy4

class DraftBoard {
    leagueFillNumbers: LeagueFillNumbers
    constructor(
        mvpBoardTeams: Array<MvpBoardTeam>
    ){
        this.leagueFillNumbers = new LeagueFillNumbers(mvpBoardTeams);
    }
}

class LeagueFillNumbers {
    [key: i32]: TeamFillNumbers
    constructor(
        mvpBoardTeams: Array<MvpBoardTeam>
    ){
        for(let i = 0; i < mvpBoardTeams.length; i++){
            this[mvpBoardTeams[i].id] = new TeamFillNumbers();
        }
    }
}

class TeamFillNumbers {
    [key: string]: i32
    constructor(){
        const fantasyPositions: Array<string> = PositionHelper.getFantasyPositionList();
        for(let i = 0; i < fantasyPositions.length; i++){
            this[fantasyPositions[i]] = 0;
        }
    }
}

The compiler errors with:

ERROR TS2329: Index signature is missing in type 'assembly/index/LeagueFillNumbers'.
     :
 194 │ this[mvpBoardTeams[i].id] = new TeamFillNumbers();
     │ ~~~~
     └─ in assembly/index.ts(194,13)

ERROR TS2329: Index signature is missing in type 'assembly/index/LeagueFillNumbers'.
     :
 180 │ return this.leagueFillNumbers[mvpBoardTeamId];
     │        ~~~~~~~~~~~~~~~~~~~~~~
     └─ in assembly/index.ts(180,16)

From what I understand, I've properly declared a key signature in all of these instances. I'm not sure what the issue is. I can discern that using the [] notation to set a dynamic property on an object is part of the issue since that is the only thing that's triggered it in both of my examples here.

BVBAccelerate
  • 172
  • 1
  • 5
  • 17
  • I think you'll want to use type `string` rather than `String` throughout. [`string` is a type, `String` refers to the JS object type](https://stackoverflow.com/questions/14727044/what-is-the-difference-between-types-string-and-string). In regular Typescript compilation this would get picked up earlier but perhaps AssemblyScript intercepts the error messages. – motto Feb 08 '23 at 20:26
  • @motto thanks, I wasn't aware of that. I updated it. Also updated the question with another example I ran into. – BVBAccelerate Feb 09 '23 at 00:59

1 Answers1

0

It took me a while, but I have managed to almost solve it.

One of the problems seems to be that the class requires overloading the "[]" operator in order for the syntax a[field] to work. After trial and error, this seemed to work:

@operator("[]")
foo(k: string): i32 {
  if (k == "player_id")                     {return this.player_id;}
  else if (k == "hasStats")                 {return this.hasStats;}
  else if (k == "rank")                     {return this.rank;}
  ...

Sadly, I could not get it to work with generic types, so I did it with only the numbers. I changed number to i32.

After this, another big problem was that AssemblyScript does not currently support closures, which is what was happening with that custom sort function. So, in order to see if I can solve it, I refactored the code so that that function is standalone.

But because the Array.sort() method can only take 2 objects, and because you cannot pass the fields in this way without creating a closure, you have to sort it in the old fashioned way. I repurposed the typescript quickSort code from RosettaCode, I passed two additional parameters (field and secondaryField) and now it seems to work.

The only problem that remains is that I could not get the generics to work for that operator overloading, but maybe someone smarter than me can solve that part as well.

The code is here. It is not complete, because I used the console.log function from javascript and I didn't include the quickSort implementation, but the idea is there.

TachyonicBytes
  • 700
  • 1
  • 8