Closed cstria0106 closed 11 months ago
For uses in generics, you can use Apply :
interface Just extends Fn {
return: this['arg0'];
}
function fn<T extends string>(a: T, b: Apply<Just, [T]>) {
type JustString = Call<Just, string>;
const aLength = a.length;
const bLength = b.length;
const js: JustString = '';
const jsLength = js.length;
}
Thank you! Can you tell me what makes Call and Apply different? Looking at the comments, it looks like Call and Apply have similar behavior
Call:
Calls a HOTScript function.
Apply:
Call a HOTScript function with the given arguments.
Call does remove placeholder parameters (they are implicit), while Apply does not. examples from the docs :
type T0 = Call<Numbers.Add<1, 2>>; // 3
type T1 = Call<Numbers.Add<1>, 2>; // 3
type T2 = Call<Numbers.Add, 1, 2>; // 3
type T3 = Call<
Tuples.Map<Strings.Split<".">, ["a.b", "b.c"]>
>; // [["a", "b"], ["b", "c"]]
Does this mean that generics cannot be used with Call
to support the calling semantics of Call
?
No you can use Call
in generics, just that since the results of HOTScript are complex type computations, they can only be evaluated at the instanciation of your generics.
Your example here is a simple one, so there is a path to resolve it before instanciation, but when doing transformations on complex types (example, records), you have no other way in TS than cast. you'll see a lot of TS generics heavy libraries doing as any
cast to silence those TS errors.
But from a user point of view, using your library, there is no issue.
So here an alternate solution (not pretty) :
function fn<T extends string>(a: T, b: Call<Just, T>) {
type JustString = Call<Just, string>;
const aLength = a.length;
const bLength = (b as unknown as string).length;
const js: JustString = '';
const jsLength = js.length;
}
the user of the function passing parameters will have Call
be resolved just fine
here a concrete example of what i'm saying in tanstack router : https://github.com/TanStack/router/blob/8814f47ba42a2db5ba6a909e54ccdbd4138317b9/packages/router/src/route.ts#L626
and tanstack router is not using HOTScript, but they face the same issue, aka RouterOptions can only be resolved by the user calling the function.
This situation could be fixed if we somehow could tell typescript that the result satisfies
some shape. but satisfies
keyword does not work on generics utility types at the moment
Really thank you for your response. My issue and questions have been resolved and I will close this issue.
Code:
Error: