Skip to content

Type merging improvement => x & void = x since y & never = never, instead of u & void = illogical constraint #24852

@wesleyolis

Description

@wesleyolis

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    UnactionableThere isn't something we can do with this issue

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions