Skip to content

meta | doc/meta- type annotation in different file #3071

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Closed
AgatZan opened this issue Feb 12, 2025 · 2 comments
Closed

meta | doc/meta- type annotation in different file #3071

AgatZan opened this issue Feb 12, 2025 · 2 comments

Comments

@AgatZan
Copy link

AgatZan commented Feb 12, 2025

I see two ways: it is not well-documented or it is not provided, as I think. Or I just a duplicate these

Given: Lua file with classes (or just functions, maybe even local) without type annotations.
Needed: Create type annotations to provide suggestions, etc.

Maybe I'm wrong, but I think changing files that contain classes is a bad idea because it mixes the logic of the type with the flow of the program.

I didn't find a way to divide it.

I suggest it should look like

class_meta.lua or class.meta.lua

---@meta class

---@class MyClass
---@field a string
local MyClass = {}

---What it should do
---@param arg integer
---@return string
function MyClass:method(arg) end

return MyClass

class.lua

---@type MyClass | It should be inferred implicitly.
local MyClass = {}

function MyClass:method(arg) 
    return self.a .. arg 
end
return MyClass

But it is not working with the redefined error.

Then i try to use @overload annotation, but

+ ---@overload fun(self:MyClass, arg:integer):string

But it doesn't work either.

Also, there is a way to annotate all methods with @field, which makes initialization noisy and ugly, and doesn't give compilation suggestions for the method body. So, type annotations are needed again.

class.lua

local function method(self, arg)
    return self.a .. arg
end
---@type MyClass
local MyClass = {
    a = "", -- must init with default
    method = method
}
@AgatZan AgatZan changed the title meta | doc/meta- type annotation in different file, something like .d.ts meta | doc/meta- type annotation in different file, like .d.ts Feb 12, 2025
@AgatZan AgatZan changed the title meta | doc/meta- type annotation in different file, like .d.ts meta | doc/meta- type annotation in different file Feb 12, 2025
@tomlau10
Copy link
Contributor

Which version of LuaLS did you use?
Your example already works in current latest version (v3.13.6)
Image

  • the arg param can be correctly inferred as integer already

NOTE: I'm no author or maintainer, below are just my own opinions and use experience.

but I think changing files that contain classes is a bad idea because it mixes the logic of the type with the flow of the program.

However I don't think separating meta file for you own implementation is the best practice in LuaLS 🤔
It's because LuaLS is not designed to let you write the header file and enforce the class implementation to follow the header. 😕
There has been a similar discussion: #2741

meta files are for API documentation

Meta files are primarily used for documenting API of a native library or 3rd party library, rather than being used for type inference within your implementation. That's because you cannot change the source code of that 3rd party library to add annotation. And for library written in native code, you simply have no way to add annotation.

the @meta [name] annotation

The syntax ---@meta class means that when your code write local class = require "class", it will read the return value of your meta file (class.meta.lua in your exmaple), instead of searching the actual required file (class.lua). By no means it can auto infer the types in that same named file.

Just for your use case, at most you can add @type to the module namespace to let LuaLS enforce the type of that module table. But definitely no way for luals to auto infer local variable / local functions by just providing a meta file with the same name. This is not how @meta works.


You can also review the practices followed in the LuaLS repo itself. For instance:

  • The LuaLS repo includes annotations directly within the codebase to facilitate type inference
  • Meta files are used when there's a need to interface with third-party libraries, such as bee.filesystem, which is a native library

You may disagree with all the above, but that's how LuaLS works and designed if I understand correctly. 😅

@AgatZan
Copy link
Author

AgatZan commented Feb 13, 2025

@tomlau10 Thanks for the answer!!!

Yes, I am using the old version 3.10 and I am ashamed that I didn't mention it at the start.

@diagnostic disable looks awkward, but it suits me. Thanks again.

Meta files are primarily used for documenting API of a native library or 3rd party library

By the way, 3rds may be a lua module and, as it seems strange, using it can cause type checking errors. And, in general, I think of it as a header file, which is often used to explain and declare.

But if your opinion is even close to being correct, that's great. Maybe it should just be described more clearly, or I should spend more time thinking about it.

@AgatZan AgatZan closed this as completed Feb 13, 2025
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants