typescript - Podmienený parameter pre kaskádovú funkciu založenú na generiku


Ako spraviť parametre podmienené len v prípade, že nebol dodaný žiadny generický typ?

type Params<T> = T extends Record<string, string> ? T : never;

export const getPath =
  <T>(path: string) =>
  (params: Params<T>) => {
    const lang = getCurrentLang();

    return generatePath(path, { lang, ...(params ?? {}) });
  };

Napríklad:

const login = getPath("/:lang/login")
login() // should works without types error

const book = getPath<{ id: string }>("/:lang/books/:id")
book() // error
book({ id: "1" }) // works

Odpoveď č. 1

Môžete použiť generiká v kombinácii s podmieneným typom na vynútenie určitého návratového typu pre getPath(). Nechajte svoj generický parameter T rozširovať zväzkový typ vášho podmieneného návratového typu a niečo, čo nie je priraditeľné k tejto hodnote (napr. undefined), aby ste mohli skontrolovať, či bol zadaný generický argument alebo nie.

Ak bol odovzdaný generický argument, vráťte (param: T) => ..., inak iba () => .... Túto logiku je možné ešte viac zjednodušiť použitím n-tíc v zvyšných parametroch a rozšírovacích výrazov:
(...params: T extends Record<string, string> ? [T] : [] ) => any

export const getPath = <
  T extends Record<string, string> | undefined = undefined
>(
  path: string
): ((
  ...params: T extends Record<string, string> ? [T] : []
) => any) => {
  return null as any; // ignoring the implemetation
};

const login = getPath("/:lang/login");
login(); // works

const book = getPath<{id: string}>("/:lang/books/:id");
//    ^? const book: (param: {id: string;}) => any
book(); // error
book({id: "1"}); // works

TypeScript ihrisko


P. S. Poznámka, odstránil som implementáciu funkcie, pretože neviem, ako sú definované getCurrentLang() a generatePath() ani aký je ich návratový typ.

Súvisiace články