[Feature Request] Intersection types
I apologize if this request has been reported before, I couldn't find any. It would be great to be able to explicitly differentiate between union types and intersection types e.g.
--- @class A
local a = {foo = 1}
--- @class B
local b = {bar = "hello"}
--- @param aOrB A | B
--- @param aAndB A & B
local function someFunc(aOrB, aAndB) end
someFunc(a, a) -- no warning, but 2nd argument should give a warning
--- @param a A
local function someOtherFunc(a) end
--- @type A | B -- would prefer to use A & B and not have any warnings
local aAndB = {foo = 1, bar = "hello"}
someOtherFunc(aAndB) -- Cannot assign `A|B` to parameter `A`. - `B` cannot match `A` - Type `B` cannot match `A` Lua Diagnostics. (param-type-mismatch)
While it's possible to use an explicit class with inheritance as a workaround, this is not always viable, especially when using dynamic types with generics
--- @class C: A, B
local c = {foo = 1, bar = "hello"}
someOtherFunc(aAndB) -- no warning
-- not viable when using something like this
--- @generic T1, T2
--- @param tbl1 T1
--- @param tbl2 T2
--- @return T1 | T2 -- would like to use T1 & T2 instead to avoid the warnings
local function merge(tbl1, tbl2) end
someOtherFunc(merge(a, b)) -- Cannot assign `A|B` to parameter `A`. - `B` cannot match `A` - Type `B` cannot match `A` Lua Diagnostics. (param-type-mismatch)
The suggested syntax A & B for intersection types and A | B for union types matches several other languages, such as TypeScript and PHP.
Edit: another workaround is to enable luals.github.io/wiki/settings#typeweakunioncheck. This has its own downsides, but may be helpful for people trying to avoid the param-type-mismatch warnings
(unrelated to this feature request)
In case you don't know yet, there is a way to allow assign A|B to parameter A.
You can enable the the type.weakUnionCheck which will permit assigning a union type to a partially matched type variable.
https://luals.github.io/wiki/settings/#typeweakunioncheck
This will silent the 2 warnings in your example. I've always turned it on in my projects, but of course this behavior may not suit your need. 😄
forgot to mention that in the issue, I did see it, and turned it on personally, since I generally mean intersect types when I use |; but it'd still be nice to be able to be explicit about it 🙂
it's good advice for anyone looking for a workaround indeed
During the implementation of version 4.0, the '&' syntax was indeed added.