Closed
Description
I'm confused why the spec (section 3.10.4) allows this situation:
interface IFoo {
a: number;
}
interface IBar extends IFoo {
b: string;
}
function expectsBar(bar: IBar): void {
console.log(bar.b);
}
function providesFoo(cb: (arg: IFoo) => void): void {
cb({ a: 1 });
}
function providesBar(cb: (arg: IBar) => void): void {
providesFoo(cb); // should this be an error?
}
providesBar(expectsBar);
I would expect the indicated line to be an error, because providesFoo
will pass an IFoo
to a callback expecting IBar
, and IFoo
is not assignable to IBar
.
The relevant spec language (emphasis mine):
S is assignable to a type T, and T is assignable from S, if one of the following is true:
- S is an object type, a type parameter, or the Number, Boolean, or String primitive type, T is an
object type, and for each member M in T, one of the following is true:
- M is a non-specialized call or construct signature and S has an apparent call or construct
signature N where, when M and N are instantiated using type Any as the type argument
for all type parameters declared by M and N (if any),
- the signatures are of the same kind (call or construct),
- M has a rest parameter or the number of non-optional parameters in N is less
than or equal to the total number of parameters in M,- for parameter positions that are present in both signatures, each parameter type
in N is assignable to or from the corresponding parameter type in M, and- the result type of M is Void, or the result type of N is assignable to that of M
In this example N = (arg: IBar) => void
and M = (arg: IFoo) => void
, so the behavior is correct according to the spec because IBar
is assignable to IFoo
, but that's not what actually happening in this case, where an IFoo
is being assigned to an IBar
. Is this a bug in the spec?
Metadata
Metadata
Assignees
Type
Projects
Milestone
Relationships
Development
No branches or pull requests
Activity
danquirk commentedon Feb 28, 2015
This is an intentional type hole to support a variety of common, existing JavaScript patterns. See https://github.com/Microsoft/TypeScript/wiki/Type%20Compatibility#function-argument-bivariance