tru7
tru7

Reputation: 7212

typescript. array returning type of argument

function last(anArray:any[]) /*:????*/ {
    return anArray[anArray.length-1];
}

Without resorting to generics, is it possible to specify the return type in the function above being the type of the elements of the argument so

let strs:string[]=["aaa","bbb","ccc"];
let lastStr=last(strs);     // type of lastStr should be string

let dates:Date[]=[new Date];
let lastDate=last(dates);      // type of lastDate should be Date

Edit: Seeing the fine answer from @Titian Cernicova-Dragomir I should have stated "Without resorting to generics when invoking the function"

Upvotes: 0

Views: 743

Answers (2)

Meirion Hughes
Meirion Hughes

Reputation: 26398

You can't avoid the generics, but you don't have to specify them as they can be inferred automatically. The accepted answer is probably good enough for your needs, but there is another way...

Typescript 2.8 will introduce type inferring (its currently published as a nightly build). With it you can support (fixed-size N) tuples of arbitrary types, rather than all elements being the same type, by combining conditional-types with type-inference.

type tuple =
  [any] |
  [any, any] |
  [any, any, any] |
  [any, any, any, any];

type TupleLast<T extends tuple> =
  T extends [infer L] ? L :
  T extends [any, infer L] ? L : 
  T extends [any, any, infer L] ? L : 
  T extends [any, any, any, infer L] ? L : any;

function last<T extends tuple>(arg: T): TupleLast<T> {
  return arg[arg.length - 1];
}

enter image description here

enter image description here

Consider this answer a mental exercise of what can be done - I'm still messing with the new toys. :D

Upvotes: 2

Titian Cernicova-Dragomir
Titian Cernicova-Dragomir

Reputation: 249506

Not sure why you say 'without resorting to generics'. This is exactly the reason for generics in typescript. Using generics is not that hard:

function last<T>(anArray:T[]) :T {
    return anArray[anArray.length-1];
}
// usage

let strs:string[]=["aaa","bbb","ccc"];
let lastStr=last(strs);     // string

let dates:Date[]=[new Date()];
let lastDate=last(dates); //date

Without generics there is no way to accomplish this.

Upvotes: 1

Related Questions