Reputation: 12898
Why it is not possible to cast something that extends number
to number
?
Here is simple example in which I'm trying to pass enum as a generic argument to function.
enum Ev {A, B}
function fun<E extends number>(x: {[ix: number]: any}, e: E)
{
return x[<number>e]
}
// no error here, so I assume is true that `Ev extends number`
fun({0:0}, Ev.A)
It seems a bit inconsistent that some type extends number
but I get this error when trying to cast it to number
:
Neither type 'E' nor type 'number' is assignable to the other.
Edit: Here is almost the same example but with class instead of number
(this compiles without error):
class A {}
function fun<E extends A>(x: {[ix: number]: any}, e: E)
{
return x[<A>e]
}
Upvotes: 0
Views: 707
Reputation: 106660
Why it is not possible to cast something that extends number to number?
As Ryan has pointed out in this issue, it seems like a bug in the language; however, take note that this form of constraint is only useful when the return type of the function is the constraint on the type parameter. For example:
function f<T extends number>(input: T) : T { return input; }
var t = f(Ev.A); // t : Ev
An issue with the constraint in the function you provided, is that it doesn't prevent passing in a number value. Since it's not possible to constrain to an enum member, you might as well just define your function with the constraint on the parameter instead:
function fun(x: {[ix: number]: any}, e: number)
{
return x[e];
}
A complaint you had with doing this was that it wasn't self documenting code. I would say it's better to give your function a descriptive name that says its intent rather than relying on generics that offer no constraint benefit beyond a number
constraint. Also remember that there's no way to force a developer to write the generic part when calling the function. They can easily write fun({0:0}, Ev.A)
instead of fun<Ev>({0:0}, Ev.A)
.
Upvotes: 0
Reputation: 7367
Primitive types cannot be inherited from, as some have special "abilities" that require a special instance, and creating a new derived object would prevent that ability. For instance, there is no way to call the string constructor for a new custom derived object, so no way to apply it to a user instance. This is why nothing inherits from number, or anything else.
Upvotes: 2