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:
- How to fix "Index signature is missing in type" error?
- Typescript: index signature is missing in type when extending interface
- How to declare one type for all class methods in typescript
- Can I define a Typescript class which has an index signature?
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.
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 syntaxa[field]to work. After trial and error, this seemed to work:Sadly, I could not get it to work with generic types, so I did it with only the numbers. I changed
numbertoi32.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 typescriptquickSortcode from RosettaCode, I passed two additional parameters (fieldandsecondaryField) 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.logfunction from javascript and I didn't include thequickSortimplementation, but the idea is there.