#Why are the function signatures different?

5 messages · Page 1 of 1 (latest)

proven torrent
#
type Test<T> = [T] extends [never] ? "never" : T extends object ? "object" : T;
type Test2<T> = [T] extends [never] ? "never" : T extends object ? "object" : "other";
export async function initPlatform1<extraCtx extends object = never>(
  modules: any[],
  ctx: Test<extraCtx>,
) {}
export async function initPlatform2<extraCtx extends object = never>(
  modules: any[],
  ctx: Test2<extraCtx>,
) {}
 
initPlatform1([], {
  timezone: 'Asia/Shanghai',
});
initPlatform2([], {
  timezone: 'Asia/Shanghai',
});

This is my code, why is the function signature of initPlatform1

function initPlatform1<{
    timezone: string;
}>(modules: any[], ctx: "object"): Promise<void>

while initPlatform2 is

function initPlatform2<never>(modules: any[], ctx: "never"): Promise<void>
latent gulch
#

in the second case, T can't be inferred since it isn't used in the signature, since it isn't a result of the conditional

tall tulip
#

The key difference is the final else condition in the conditional types:

  • Test<T> ends with : T. This gives TypeScript a direct structural template to infer the generic extraCtx from the object you pass in.
  • Test2<T> ends with : "other". This provides no structural information. TypeScript cannot infer the shape of extraCtx from a simple string literal, so it fails to infer a specific type and falls back to the default never.
proven torrent
proven torrent