Skip to content

No common supertype between {optional, optional} and {required, absent} #1446

Closed
@JsonFreeman

Description

@JsonFreeman

We made the change that an object type with a missing property cannot be a subtype of an object with an optional property. This made subtype choose better results in some cases, because it fixed cases of nonantisymmetry in the subtype relation. But now there are cases where you get an error in type argument inference because a pair of type has no common supertype.

interface I {
    a?: string;
    b?: string;
}

var i: I;

function foo<T>(p1: T, p2: T) { }

foo(i, { a: "" }); // Error because neither type is a supertype of the other

One interpretation is that in this case I should be the common supertype. To make this happen, we would say that instead of a missing property being a supertype of an optional, it is a subtype. In this view, missing and required are both specific cases of optional, and optional is a supertype of both.

Another fix is a change in type argument inference. If finding a common supertype does not yield a result, we can have another round where we use assignability. In the above example, this would not produce an error, since the object literal is assignable to I.

The issue here is that it may lead to results that depend on the order of the arguments. Both would select the first type in the following case:

interface I1 {
   a?: string
}
interface I2 {
   b?: string
}
var i1: I1, i2: I2;
foo(i1, i2);

Both proposed fixes would choose I1 because it is first, whereas now we at least get an error consistently no matter the argument order.

Metadata

Metadata

Assignees

Labels

Breaking ChangeWould introduce errors in existing codeBugA bug in TypeScriptFixedA PR has been merged for this issueQuestionAn issue which isn't directly actionable in codeSpecIssues related to the TypeScript language specification

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions