-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Type merging improvement => x & void = x since y & never = never, instead of u & void = illogical constraint #24852
Description
Hi Guys,
I would just like to challenge some of the types engine logic here for the greater good of patterns.
I would like to recommend a change to the logic of how intersections are resolved with regards to void and never, which I see as reciprocal operations.
I would like to suggest think of/working with sets theory, then the type keywords void and never have specially meaning. cumulative, associative, distributive laws come to mind from probability and stats.
This would improve build up of types with recursion, were a default initial condition can be supplied.
Similar to SQL tricks of "1 == 1" + $WereConditional
The following similar explanation I have offered for SQL language comes to mind that I have previously given. Extract
Select rowid From BackColors where col1 not in (Select col_in From table_in where col_in is not null)
Very import in the sub-query the SQL statement in bold, italics, red is the part where the column on which the lookup is to be done, must exclude nulls. Reason a NULL will match anything, thus it will return no records to highlight.
If you imagine null as a set and null means the set is empty (nothing) then what is the not or opposite NULL then? Not of empty is full and the not of nothing is everything. This is the reason why you have to exclude nulls from the subquery as you noting the result which in tern then is everything.
Current Typescript Behavior:
void type identifier
type inter = (number | string) & void;
// impossible logical condition to meet.
const example : inter = ... ;// type must be of form number & void | (string & void), which is an impossible condition to meet.
never type identifier
type nothingEmpty = (number | string ) & never; // = never
const example : nothingEmpty = ...; //type must be of form never, removes item or type.
Suggested Behaviour, perceived improved behaviour
void type identifier
type inter = (number | string) & void;
const example : inter= 34; // Ok, type must be of form number | string
const example : inter= "testst"; // OK, type must be of form number | string
never type identifier
type nothingEmpty = (number | string ) & never; // = never
const example : nothingEmpty = ...; //type must be of form never, removes item or type.
One may also want to introduce boundaries for type simplification/resolution such as intersections and unions,
which will communicate to the compiler, were it should no longer simplify void and never conditions.
Think of using some form of brackets []. This cases below are not practical, however, example of the pattens.
[number & void] & string = number & string
or
[number & never] & string = string
Looking forward to your feedback.