I am learning about typescript generics. I have created a generic function like the following:
function getRandomElement<T>(items: T[]): T {
let ranIndex = Math.floor(Math.random() * items.length);
return items[ranIndex];
}
then I intentionally called that function and passed type only (not passing argument into the function).
let result = getRandomElement<number>;
Then I expected that Ts compiler give me error message about creating result variable statement, But nothing happened. result after that became a function ((items: number[]) => number
).
I want to study more about this feature of typescript. But after search a while I don't find any essential information talking about.
Could you help explain this feature or give me a keyword about it? Thanks for considering my stupid question.
getRandomElement<number>
is an instantiation expression, as implemented in microsoft/TypeScript#47607 and introduced in TypeScript 4.7.
We've always been able to manually specify a generic function's type arguments when we call it, like f<X, Y>(a, b, c)
:
declare const f: <T, U>(x: T, y: U, z: T[]) => [T, U]
// const f: <T, U>(x: T, y: U, z: T[]) => [T, U]
declare const a: X;
declare const b: Y;
declare const c: X[];
f<X, Y>(a, b, c); // calling a generic function
but instantiation expressions let you do that without calling it, like f<X, Y>
. That is, you can now write (f<X, Y>)(a, b, c)
, where f<X, Y>
is its own expression:
(f<X, Y>)(a, b, c); // calling an instantiation expression
The resulting function (f<X, Y>)
is not generic, and can be saved to its own variable:
const g = (f<X, Y>);
// const g: (x: X, y: Y, z: X[]) => [X, Y]
This function can then be called reused with the same type arguments:
g(a, b, c);
declare const d: X;
declare const e: Y;
g(d, e, [a, d]);