TypeScript Version: 2.0.3
linq.d.ts:
interface Array<T> {
ofType<TResult>(type:typeof TResult):TResult[]
}
Expected behavior:
No errors.
Actual behavior:
produces error:
[ts] Cannot find name 'TResult'.
@MeirionHughes If you are after behavior analogous to C#'s
IEnumerable<TResult> Enumerable.OfType<TResult>(this IEnumerable<T>);
you can simply write
interface Array<T> {
ofType<TResult>(): TResult[];
}
The reason you get the error
[ts] Cannot find name 'TResult'.
is because typeof expects a value and TResult is a type. For example, when acting upon a class, the case where it is most commonly used, it is the class's value that is the operand.
@aluanhaddad I think @MeirionHughes probably want something like this, if I read the C# counterpart correctly.
interface Array<T> {
ofType<R extends T>(RType: { new(...args: any[]): R}): R[]
// probably you also need overloading for builtin Number, String, Boolean
}
//usage
var animals: Animal[] = [new Cat, new Dog, new Fish]
var cats: Cat[] = animals.ofType(Cat)
Please first checkout FAQ before submitting issues. You probably want to pass a constructor to ofType so that array values can be filtered at runtime.
@aluanhaddad I think your approach can only make Array<TResult> but not runtime. C#'s generic is reified at runtime, but TypeScript's is erased. So users must have a value to figure out which type should be used as filter criteria.
@HerringtonDarkholme yes, that { new(...args: any[]): R works perfectly.
is because typeof expects a value and TResult is a type. For example, when acting upon a class, the case where it is most commonly used, it is the class's value that is the operand.
Okay thx, I'll close this then.
@HerringtonDarkholme great point, I was being overly literal. Another, perhaps more flexible approach would be to take a typeguard as the argument.
interface Array<T> {
ofType<TResult extends T>(guard: (x: T) => x is TResult): TResult[];
}
Most helpful comment
@aluanhaddad I think @MeirionHughes probably want something like this, if I read the C# counterpart correctly.
Please first checkout FAQ before submitting issues. You probably want to pass a constructor to
ofTypeso that array values can be filtered at runtime.@aluanhaddad I think your approach can only make
Array<TResult>but not runtime. C#'s generic is reified at runtime, but TypeScript's is erased. So users must have a value to figure out which type should be used as filter criteria.