lua-language-server icon indicating copy to clipboard operation
lua-language-server copied to clipboard

Disallow ? on values

Open mikuhl-dev opened this issue 1 year ago • 6 comments

How are you using the lua-language-server?

Visual Studio Code Extension (sumneko.lua)

Which OS are you using?

Windows

What is the issue affecting?

Type Checking

Expected Behaviour

? is not a type, and should only be used when marking fields as optional. If nil is explicitly allowed as a value, | nil should be used. This is in line with TypeScript.

Actual Behaviour

? does not add | nil to the value type, and the second option should be disallowed. image

Reproduction steps

---@class Foo
---@field foo? string
---@field bar string?
---@field baz string | nil
local test = {};

function Foo()
    return test.foo, test.bar, test.baz
end;

Additional Notes

No response

Log File

No response

mikuhl-dev avatar Aug 21 '24 04:08 mikuhl-dev

? is not a type, and should only be used when marking fields as optional

No, in luals ? is also shorthand for marking the type as |nil. They (should) have the same effect, and the following is valid:

---@return table?
local function test()
end

local t = test()    -- table?
print(t.a)          -- warning: need check nil


But I agree that in your example, it is a bug. When you do hover preview over test.foo and test.bar on the return line, they actually get inferred correctly as string?. But the overall inferred function signature incorrectly treat them as string 🤔

tomlau10 avatar Aug 21 '24 08:08 tomlau10

I feel like there should not be three ways to do essentially the same thing. ? on types are disallowed in TypeScript, and I think LuaLS should try to match the behavior wherever it can. ? should have one specific function and that should be making properties optional.

mikuhl-dev avatar Aug 21 '24 12:08 mikuhl-dev

I feel like there should not be three ways to do essentially the same thing

I agree with you personally, and this has been discussed previously in: https://github.com/LuaLS/lua-language-server/issues/2070#issuecomment-1510456403, https://github.com/LuaLS/lua-language-server/issues/2029#issuecomment-1484642935.

But as discussed in those issues, any change in the behavior of the current annotation syntax will be a breaking change. So this may not be implemented in anytime soon ☹️ given that implementing this gives no extra function to luals itself. As a user of luals, we might just stick to our own practices in our own projects to keep the consistency.

And this issue seems like a duplicate one now.

tomlau10 avatar Aug 21 '24 14:08 tomlau10

Also, Lua is not Typescript, and trying to pretend it is will only lead to more confusion down the line. (In particular, Lua itself does not distinguish between optional and explicit nil arguments.)

clason avatar Aug 22 '24 08:08 clason

Also, Lua is not Typescript, and trying to pretend it is will only lead to more confusion down the line. (In particular, Lua itself does not distinguish between optional and explicit nil arguments.)

Lua do actually distinguish between nil and optional in function calls

Example: table.insert(t, nil) -- Valid table.insert(t) -- Error, "wrong number of arguments"

Rathoz avatar Sep 02 '24 08:09 Rathoz

Furthermore you can detect an explicit nil on varargs (...) via select('#', ...), so it is possible for it to have a semantic difference.

lewis6991 avatar Sep 02 '24 09:09 lewis6991