Why can't void and {} be inferred as never type in TypeScript?
P粉548512637
2023-09-04 16:03:52
<p>I get different results when I use TypeScript's void type with other types using cross types. </p>
<pre class="brush:php;toolbar:false;">type A = void & {} // A is void & {}
type B = void & '1' // B is never
type C = void & 1 // C is never
type D = void & string // D is never
type E = void & String // E is void & String</pre>
<pre class="brush:php;toolbar:false;">type A = void & {}
type E = void & String</pre>
<p>They should also be of type never, right? </p>
{}andStringare both object types, whilestringand'1'are both primitive types. You can intersectvoidwith object types because object types intersect by adding properties:type A = { foo: number } & { bar: string } // { foo: number, bar: string }In contrast, primitive types intersect by reducing the set of possible values:
And by intersecting a primitive type with an object type, you can add new properties to the primitive type:
type C = string & { foo: number } declare const c: C c.foo // numberBut a primitive type can never become another primitive type. Therefore, intersecting two different primitive types will result in
neverFinally,
voidis a primitive type.So, this means
void & { foo: number }means that the primitive typevoidwill also have the attributefoo.However,
void & stringwill produceneversince they are two different primitive types.However,
void & Stringare properties ofvoidplusString, becauseStringis an object type (vianew String()Create).However, all this means nothing. You cannot assign
voidto anything other thanundefined, andundefinedcannot have properties. So I thinkvoid & Typehas no reason to exist in your codebase. If you think you need it, I would ask you why you need it and try to refactor the code so that it doesn't need it.