Open
Description
TypeScript Version: 3.4.0-dev.201xxxxx
Code
declare let x: Partial<HTMLElement>;
function f<T>(y: T) {
x = y;
}
f({ innerHtml: Symbol() }); // this is blatantly incompatible with `HTMLElement`
if (x.innerHTML) {
x.innerHTML.toLowerCase(); // We just set it to a `symbol` and not a `string`, this will error at runtime
}
Expected behavior:
An error on x = y
.
Actual behavior:
No error.
The root cause is this relationship in structuredTypeRelatedTo
added way back in this:
if (relation !== subtypeRelation && isPartialMappedType(target) && isEmptyObjectType(source)) {
return Ternary.True;
}
This is unsound when source
is the empty type resulting from the constraint of an unconstrained generic type (which, if changed to unknown
, catches this issue!). It's unsound when it comes from a constraint at all, actually. Fixing this will break react-redux
, whose recursive Shared
type (which we have in our test suite) actually only checks because of this unsoundness.