Maison  >  Article  >  interface Web  >  Surcharge de fonction TS - exemple réel

Surcharge de fonction TS - exemple réel

王林
王林original
2024-08-09 20:32:501138parcourir

Plongeons dans une fonctionnalité Typescript moins fréquente - surcharge de fonctions avec un exemple réaliste.

Introduction

Avoir un crochet personnalisé

export function useUrlState<T extends JSONCompatible>(
  defaultState: T,
  searchParams?: object,
)

À un moment donné, je dois y ajouter plus d'arguments, peut-être plus à l'avenir. Difficile de se rappeler ce qu'est le Nième argument, et appeler une fonction comme useUrlState(firstArg, null, null, quarterArg) est ridicule. Il sera bien plus simple de passer des arguments à l'intérieur d'un objet comme ceci :

export function useUrlState<T extends JSONCompatible>({
  defaultState,
  searchParams,
  replace
}: { defaultState: T, searchParams?: object, replace?: boolean })

Je convertirai la fonction dans un nouveau format et la garderai rétrocompatible avec l'implémentation existante.

Mise en œuvre

Tout d'abord, vous devez ajouter des signatures de surcharge juste au-dessus de la fonction implémentation. Les signatures de surcharge sont toutes les manières possibles d'appeler une fonction, avec différents types et quantités d'arguments.

/**
 * @deprecated Pass arguments in a object `useUrlState({ defaultState: form, searchParams })`
 *
 *  * Github {@link https://github.com/asmyshlyaev177/state-in-url/tree/main/packages/urlstate/next/useUrlState#api}
 */
export function useUrlState<T extends JSONCompatible>(defaultState: T, searchParams?: object): {
  state: DeepReadonly<T>,
  updateState: (value: Partial<DeepReadonly<T>>,
  updateUrl: (value?: Partial<DeepReadonly<T>>) => void,
  getState: () => DeepReadonly<T>
}
/**
 * NextJS hook. Returns `state`, `updateState`, and `updateUrl` functions
 *
 * @param {JSONCompatible<T>} [defaultState] Fallback (default) values for state
 * @param {?SearchParams<T>} [searchParams] searchParams from Next server component
 */
export function useUrlState<T extends JSONCompatible>({ defaultState, searchParams }: {
  defaultState: T, searchParams?: object, replace?: boolean
}): {
  state: DeepReadonly<T>,
  updateState: (value: Partial<DeepReadonly<T>>) => void,
  updateUrl: (value?: Partial<DeepReadonly<T>>) => void,
  getState: () => DeepReadonly<T>
} // <- notice that should implicitly define returned value
// implementation
export function useUrlState<T extends JSONCompatible>(
  defaultState: T | { defaultState: T, searchParams?: object, replace?: boolean },
  searchParams?: object,
) {

La partie délicate est que les signatures doivent être compatibles avec l'implémentation, donc ayez cet état par défaut : T | { defaultState : T, searchParams ? : objet, remplacer ? : booléen }

Je suppose que si le premier argument a une clé spécifique, il s'agit d'un nouveau format d'objet.

  const _defaultState = ('defaultState' in defaultState ? defaultState.defaultState : defaultState) as T
  const _searchParams = ('defaultState' in defaultState ? defaultState.searchParams : searchParams) as object | undefined
  const _replace = ('defaultState' in defaultState ? defaultState.replace ?? true : false) as boolean

Vous remarquerez également que l'argument de remplacement a la valeur par défaut true pour un nouveau format, mais pour l'ancien, il est faux.

Voyons comment cela fonctionne.

TS function overloading - real world example

Remarquez que nous avons des commentaires JSDoc différents pour chaque signature, l'ancien étant marqué de la balise @deprecated.

Documents officiels https://www.typescriptlang.org/docs/handbook/2/functions.html#function-overloads

Tnx pour la lecture :)

Laissez un commentaire sur votre expérience, ou si vous avez des idées pour le faire de manière plus élégante.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn