TypeScript Version: 2.3.3 / master up to and including e2cc27b / since 424074b
Code
interface SomeType {
name: string,
size: number
}
var someObject:SomeType = { name: 'thing', size: 42 };
// the type (never & T) should reduce to never, but instead reduces to T:
var badIntersection: never & SomeType = someObject;
// but since (o ∈ A∩B) implies (o ∈ A)
function upcast<A, B>(o: A & B): A {
return o;
}
// then you can convert any value to type never
function toNever<T>(o: T): never {
return upcast<never, T>(o);
}
// which seems like a problem
var seemsLikeAProblem: never = toNever('weirdness');
Expected behavior:
The type never is a bottom type; its set of possible values is empty. The intersection of any type with never should reduce to never.
Actual behavior:
The type checker reduces never & T to T. One bizarre consequence is the ability to cast any value to never.
This behavior was introduced in 424074b as a reduction rule appropriate for union types (as never | T should indeed reduce to T), and has been preserved ever since, most recently in b673d5f. It looks like an oversight and a bug to me, but maybe people rely on this behavior somewhere?
TypeScript Version: 2.3.3 / master up to and including e2cc27b / since 424074b
Code
Expected behavior:
The type
neveris a bottom type; its set of possible values is empty. The intersection of any type withnevershould reduce tonever.Actual behavior:
The type checker reduces
never & TtoT. One bizarre consequence is the ability to cast any value tonever.This behavior was introduced in 424074b as a reduction rule appropriate for union types (as
never | Tshould indeed reduce toT), and has been preserved ever since, most recently in b673d5f. It looks like an oversight and a bug to me, but maybe people rely on this behavior somewhere?