luau icon indicating copy to clipboard operation
luau copied to clipboard

Introduce a lint for "TypeUnused"

Open JohnnyMorganz opened this issue 10 months ago • 3 comments

If a non-exported type alias is defined in a file but it is not used, it should be reported as a lint, similar to LocalUnused:

local x = false -- LocalUnused: Variable 'x' is never used; prefix with '_' to silence

type Foo = {} -- no lint

JohnnyMorganz avatar Feb 15 '25 12:02 JohnnyMorganz

What would be the silencing path?

Multiple types named _ are not allowed.

vegorov-rbx avatar Feb 17 '25 12:02 vegorov-rbx

Wouldn't prepending the name with an underscore be fine (_FOO), like with local unused variables?

dibrinsofor avatar Mar 02 '25 07:03 dibrinsofor

Interesting question, I did not think about the type names colliding. Although I do wonder what is the value for having multiple types with _ name.

For variables, it makes more sense, as we need a way to discard values. For example, when a function returns multiple items, and you only care about the second:

local _, value = call()

for _, v in tbl do
end

On the other hand, there is no situation with types where you need to "discard" a type. It's only attached as extra information.

Personally, this lint would be valuable to me as an unused type typically correlates to user error (e.g. forgetting to add the type to a union, or there's a typo with another types name). To me there otherwise seems to be no reason for the declaration to exist in the first place if unused. OTOH, one could argue that in both the examples mentioned, it would likely lead to a TypeError caught by the type system down the line, but a lint can highlight the issue more directly. The source code cleanliness is an added benefit :)

type AstExprNumber = { ... }
type AstExprString = { ... }
type AstExprBool = { ... }
type AstExpr = AstExprNumber | AstExprString -- bool is missing. TypeUnused would highlight this

If we still want a silencing path, then I think prefixing a type name with _ does still make sense. (type _Foo = ....; type _Bar = ...). I'm not sure what to do about multiple types named as _ though. Either we leave it alone (surely a type should at least have some sort of unique name, and prefixing with _ will just work), or allow shadowing just for this case, but there seems to be no value in it IMO.

Just my (biased) opinion though, maybe there are cases that I have not considered.

JohnnyMorganz avatar Mar 16 '25 15:03 JohnnyMorganz