Benjamin-Dobell / IntelliJ-Luanalysis

Type-safe Lua IDE — IntelliJ IDEA plugin
Apache License 2.0
154 stars 21 forks source link

Support for intersection types (`&` operator) #119

Open LoganDark opened 2 years ago

LoganDark commented 2 years ago

The ability to do @type table<string, string> & number[] to say that it is both a string->string table and an array of numbers

Benjamin-Dobell commented 2 years ago

You've got union and intersection types around the wrong way; currently only union types are supported. There are no intersection types.

That said, with the specific example you've given, an equivalent type can be defined as:

---@shape NumberArrayStringMap
---@field [number] number
---@field [string] string

---@type NumberArrayStringMap
local numberArrayStringMap1 = {}

---@type { [number]: number, [string]: string }
local numberArrayStringMap2 = {}

Would like intersection support, however honestly it's probably a way off. Currently it's not yet possible to extend multiple shapes, that'd need to come first.

LoganDark commented 2 years ago

currently only union types are supported. There are no intersection types.

Union types support all operations of all types, intersection types only support operations that both types support. Is that backwards?

That said, with the specific example you've given, an equivalent type can be defined as:

---@shape NumberArrayStringMap
---@field [number] number
---@field [string] string

---@type NumberArrayStringMap
local numberArrayStringMap1 = {}

---@type { [number]: number, [string]: string }
local numberArrayStringMap2 = {}

Thanks!

Benjamin-Dobell commented 2 years ago

https://www.typescriptlang.org/docs/handbook/unions-and-intersections.html#intersection-types

LoganDark commented 2 years ago

https://www.typescriptlang.org/docs/handbook/unions-and-intersections.html#intersection-types

I fucking hate type theory and how everything is backwards, I mean, intersection literally means where two things collide / have in common, but whatever

Feuermurmel commented 1 year ago

https://www.typescriptlang.org/docs/handbook/unions-and-intersections.html#intersection-types

I fucking hate type theory and how everything is backwards, I mean, intersection literally means where two things collide / have in common, but whatever

Yes, that's type theory! 😁 The more options you have in a type, the fewer things you know about its values. Or you can think about it this way: The properties of a type (e.g. what fields you can access) are a function what values are not part of the type (the type's complement, it's all just set theory btw.). The more values you can rule out, the more properties you know are guaranteed. If you look at the complement of types, the intersection of two types become their union and vice-versa.

So if you take the union of what you can rule out in two types, you get the union of the types' properties…


I have another example I've run into where I wanted to use an intersection type. I'm writing type stubs for a library that provides functions inside of tables in global variables. Some of these functions are overloaded, so I can write (without any require):

foo.bar()
foo.bar(42)

To type this, I wanted to write the following declaration (pseudo-syntax) in a stub file (a Lua file that I'm never importing):

---@shape Foo
---@field bar fun() & fun(a: number)

foo = --[[---@type  Foo]] {}

Instead, I managed to get the result I wanted with this:

---@shape Bar
---@overload fun()
---@overload fun(a: number)

---@shape Foo
---@field bar Bar

foo = --[[---@type  Foo]] {}