Open rraval opened 5 years ago
I can see how this is super inconvenient.
I'd like to just put this silly example here, though,
class A {
public uniqueToA = "a";
public getString(this: A): string {
return this.uniqueToA;
}
}
class B {
public uniqueToB = "b";
public getString(this: B): string {
return this.uniqueToB;
}
}
function newAOrB () : A|B {
return new A();
}
const aOrB : A|B = newAOrB();
function f(model: A | B): string {
model.getString = aOrB.getString;
return model.getString();
}
const b = new B();
const result = f(b);
//Expected: `"b"`
//Actual : undefined
console.log(result);
Three options:
I'm not entirely sure raising an error here is correct. At least, according to this work on intersection and union types , an evaluation context that consumes a union type is well typed if it's well typed for both types independently. It seems like the evaluation context:
x.getString() // x is the evaluation context were something of A or B may be placed
is well type if you assume x
has type A
, or if x
has type B
.
The example by @AnyhowStep is unsound because the property update is unsound, not the call.
Looking back at the motivation example from the PR #31547, there is a difference which is that the union of functions comes from the property itself, not from a synthesis of a union of objects.
So I wonder if the correct thing here is to not intersect this
types for calls to synthetic unions obtained from reading a property.
In other words: you typically need to convert a union to an intersection when the context that introduces the union is different from the context that consumes the union---you have no assurances about which branch is chosen. In examples like the OP, the context that produces the union is similarly responsible for providing the this
used to consume the union, so the producer and consumer are really the same thing.
TypeScript Version: Version 3.6.3, Version 3.7.0-dev.20190911
Search Terms: intersect function
Code
Expected behavior:
In Typescript 3.5.3, the
model.getString()
infunction f
has no error.Actual behavior:
In Typescript 3.6.3 and 3.7.0-dev.20190911, the code above gets the following errors:
Playground Link: http://www.typescriptlang.org/play/#code/MYGwhgzhAECC0G8BQ1XQA4FcBGICWw0mAdngI6YCmAKgPbwC80ARGMwNxIppa4HQBzSgBcAysIBOeYgIAUwgBZ4IALjgBKNREnSBibmjQSRmCcRZtOhgL5JbSUJBgAhfYd75CJclTqumzNgcXO44noIi4lIy8kqq0M6a0NrResiGhsbCpuaBwTZ2XABmJMDCeLTmRbIAtrQAJpQgavAAPglJKbpuRiZm0HWNIAB0QmI6Meqc1kA
Related Issues: #32506