Help with Typed Luau and Dictionaries

I have just tested what I made and it seems like Roblox doesn’t like what I did there.

This is the fixed version, sorry for the confusion

type possibleKeys = 'niceKey'|'coolKey'
local args: {[possibleKeys]: string}
2 Likes

Removing the parentheses appears to throw an error, so I also tried making it into a Type, but this too doesn’t seem to work:

--!strict

export type Argument = {
	description: string,
	parse: () -> (),
}

type ArgumentType = "player" | "color" | "speed"

local Args:{[ArgumentType]: Argument} = {
	["player"] = {
		description = "",
		parse = function() end,
	},

	["color"] = {
		description = "",
		parse = function() end,
	},

	["speed"] = {
		description = "",
		parse = function() end,
	},
}

print(Args)

return Args

RobloxStudioBeta_dTyBtz1Gh1

1 Like

That’s odd. Seems like Luau doesn’t support that, even tho it shows the correct type

2 Likes

It’s funny because you’d assume this would work too… but sadly it doesn’t seem to :melting_face:

3 Likes

I tested it with the new Beta type solver as well, seems like it also doesn’t support that either. Hopefully this will be fixed with the full release of the new type solver

1 Like

Would you be okay if I reported this as a bug to roblox?

2 Likes

This seems like more of a bug then a solvable question. (Unless I understood your issue in the wrong way that is.)

Though it’s just a rough guess but try using the --!strict type-checking mode.

1 Like

Seems like that doesn’t work either, im pretty sure this unintended and indeed a bug

2 Likes

Yes because I really don’t have a idea on how this could be actually intended.

2 Likes

I agree, I’m going to test a few things and then write a bug report in a minute

1 Like

This isn’t really a solution but rather an explanation. From what I can tell, primitive dictionary types (denoted as {[k]: v}) only accept primitive values as keys in contrast to complex “dictionary” types (they behave more like objects), which allow you to use literal types as keys and assign each key a unique type. Now I don’t think this is a bug, especially when you consider that you’re denoting a common key and value type respectively anyways, which would defeat the purpose of using it in the first place.

2 Likes

Yes please, a bug report would be awesome if we can’t find any other reason why this would happen :pray:

If you share a link of that bug report afterwards I can make it the solution

2 Likes

The reason for denoting the string and Argument types is so that every sub-dictionary (such as Args.player) automatically registers as the type ‘Argument’. Unless there’s an alternative way to do this easily, enabling us to not specify types, I’d still consider this an unintended feature which would benefit from being reported.

2 Likes

Well the only way to achieve what you want is to just assign the argument type to each possible key literal, which could look something like:

type someType = {
  player: Argument,
  -- Alternatively ["player"]: Argument
  color: Argument,
  speed: Argument
}
1 Like

This is completely valid but I still do think not being able to annotate literals to dictionary keys is a flaw and that it should get implemented

2 Likes

As I said in my first post, primitive dictionary annotations aren’t really meant for that. They are simply used to denote a common key and value type that is the same through out the entire table, whereas the type of annotation I proposed is exactly meant for that where a common key or value type may or may not be present.

Edit: keep in mind that literals are not valid key types anyways, they are polymorphic unless collapsed into a certain state, therefore are not hashable.

1 Like

Sounds good.

Hope this gets fixed.

I suppose ForeverHD can mark your post as the solution now as this really isn’t an issue solvable by us users.

1 Like

Those are valid points, do you think annotating Literals to primitive dict keys should be a thing?

It would allow for the following aswell (im aware this isn’t very useful)

type someDict<UnionOfLiteralKeys> = {[UnionOfLiteralKeys]: someType}
1 Like

I personally don’t think it should be a thing as simply denoting each possible key literal as a different key and assigning the appropriate type to it does the job pretty well, and in my opinion would be a lot more readable than this.

2 Likes
2 Likes