Agregar TypeScript a @WordPress/Data Stores

El año pasado hablé mucho sobre TypeScript. En una de mis últimas publicaciones, hemos visto cómo usar TypeScript en los complementos de WordPress a través de un ejemplo real y, en particular, cómo mejorar una tienda Rodux que agrega tipos a nuestros selectores, acciones y reductores. En el ejemplo mencionado, pasamos del código Basic JavaScript, como sigue: // Selectores Función GetPost (State, ID) {…} Función GetPostsInday (Estado, Día) {…} // Función de acciones RecibenEngeWpost (post) {…} Función UpdatePost (PostId, Attributes) {…} // Reductor Función Reductor (estado, acción) {} donde nos dio pistas sobre lo que hace cada función y lo que cada parámetro depende de nuestras habilidades de nombre, en el siguiente mecanografiado aprobado mejorado:
// Función de selectores GetPost (Estado: Estado, ID: PostId): Post | Función {…} indefinida getPostsInday (estado: estado, día: día): postid [] {…} // Función de acciones ReceptiveWpost (post: post): recibeVNewPostction {…} Función UpdatePost (postID: PostId, atributos: parcial {const = useElect ((select): post => select (‘Non-Store’) .getPost (postID);); const {updatePost} = UsedIsPatch (‘Non-Store’); devolver (…); }; En el fragmento anterior, puede ver que accedemos a nuestros selectores y acciones utilizando los ganchos React. Pero, ¿dónde diablos sabe TypeScript que existen estos selectores y acciones, sin mencionar sus tipos?
Bueno, ese es exactamente el problema que enfrenté. Quiero decir, quería saber cómo podría decir TypeScript que el resultado de seleccionar Select (‘Neli-Store’) es un objeto que contiene todas nuestras tiendas y selectores de despacho (‘neli-store’) es un objeto con nuestras acciones en la tienda. . La solución en nuestra última publicación sobre TypeScript hablamos sobre las funciones polimórficas. Las funciones polimórficas nos permiten especificar diferentes tipos de retorno en función de los argumentos dados. Bueno, utilizando el polimorfismo de mecanografiado, podemos especificar que cuando llamamos a los métodos de selección o envío de @WordPress/Date con el nombre de nuestra tienda como parámetro, el resultado que obtenemos son nuestros selectores y nuestras acciones respectivamente. Para hacer esto, puro, puro Y simplemente agregue un bloque de módulos de declaración al archivo en el que registramos nuestro almacén, como sigue: // WordPress Dependencias Import {RegisterStore} de ‘@WordPress/Data’; Import {controles} de ‘@wordpress/data-confrols’; // Reductor de importación de dependencias internas de ‘./reducer’; Importar * como acciones de ‘./acciones’; Import * como selectores de ‘./selectors’; const store = ‘sin tienda’; RegisterStore (tienda, {controles, reductor, acciones, selectores,}); // extender @wordpress/data con nuestro almacén declara módulos ‘ @wordpress/data’ {function select (clave: typeof store): selectores; FUNCIÓN DESPACIOS (CLAVE: TypeoF Store): Acciones; } y luego defina qué tipos de selectores y acciones son realmente:
Type selectors = {getPost: (id: postid) => post | no afinado; GetPostsInday: (día: día) => postid []; } Type Actions = {recibeVNewPost: (post: post) => void; UpdatePost: (postID: postid, atributos: parcial ) => void; } Hasta ahora, está bien, ¿verdad? El único “problema” es que tenemos que definir manualmente los tipos de selectores y acciones, lo que suena extraño, teniendo en cuenta que ese mecanografiado ya sabe que tenemos un conjunto de selectores y acciones correctamente … manejando los tipos de funciones en TypeScript si Mire en los tipos de acciones y selectores que importamos, veremos que TypeScript nos dice lo siguiente: TypeoF Selectors === {getPost: (estado: estado, id: postid) => post | no afinado; GetPostsInday: (Estado: Estado, Día: Día) => PostId []; } Typeof Actions === {RecedgeWeWpost: (post: post) => recibeVnewPostction; UpdatePost: (postID: postid, atributos: parcial ) => updatePostction; } Como puede ver, sus tipos son una copia exacta de los tipos que hemos definido manualmente en la sección anterior. Bueno, casi exactamente: a los selectores le faltan el primer argumento (estados de la tienda, porque no está presente cuando llamamos a un selector de seleccionar) y las acciones devuelven void (ya que las acciones nombradas por el despacho no devuelven nada).
¿Podemos usarlos para generar automáticamente los tipos de selectores y acciones que necesitamos? Cómo eliminar el primer parámetro de un tipo de función en TypeScript para enfocarse por un momento en el selector GetPost. Su tipo es el siguiente: // typeOf typeOf GetPost === (estado: estado, id: postid) => post | Undefinado como acabo de decir, necesitamos un nuevo tipo de función que no tenga el parámetro de los estados: // nuevo tipo (id: postid) => post | Por lo tanto, necesitamos TypeScript para generar un nuevo tipo de tipo existente. Esto se puede lograr combinando varias funcionalidades de lenguaje avanzado: type omitFirstarg = f extiende (x: any, … args: infer p) => infer R? (… args: p) => r: nunca; Complicado, ¿verdad? Echemos un vistazo más de cerca a lo que está sucediendo aquí:
Escriba omitfcerstarg . En primer lugar, definimos un nuevo tipo auxiliar genérico (omitfirstarg). En general, un tipo genérico es un tipo que nos permite definir nuevos tipos de tipos existentes. Por ejemplo, probablemente esté familiarizado con el tipo de matriz , ya que le permite crear listas de cosas: la matriz es una lista de cadenas, la matriz es una lista de trabajo, etc. Bueno, la siguiente noción, omitfirstarg es un tipo de ayuda que elimina el primer argumento de una función.
Dado que este es un tipo genérico, teóricamente podríamos usarlo con cualquier otro tipo de TypeScript. Es decir, cosas como omitfirstarg y omitfirstarg son posibles … incluso si sabemos que este tipo solo debe usarse con funciones que tienen al menos un argumento. Para garantizar que este tipo de ayuda se use solo con funciones, la definiremos como un tipo condicionado. El tipo condicional nos permite especificar qué tipo de resultado debe basarse en una condición: “Si F es una función con al menos un argumento (condición), el tipo de resultado es otra función en la que se ha eliminado el primer argumento (tipo cuando el tipo cuando el tipo de condición esto es cierto); De lo contrario, use el tipo de nunca (escriba cuando la condición sea falsa) ”. F extiende xxx. Esta es la fórmula para especificar la condición. ¿Quieres verificar si F es una cadena? Solo escriba: F extiende la cadena. Fácil de sacudir. Pero, ¿qué pasa con “una función con un solo argumento?” Ciertamente suena más complicado …
(x: cualquiera, … args: inferir p) => inferir r. Este es un tipo de función: comenzamos con los argumentos (en entre paréntesis), seguido de una flecha, seguido del tipo de retorno de la función. En este caso particular, solicitamos que la función tenga un argumento X (cuyo tipo específico es irrelevante). Esta definición de tipo tiene dos partes interesantes. Por un lado, usamos el operador REST para capturar los tipos de Args restantes (si los hay). Por otro lado, utilizamos la inferencia de tipos de TypeScript (inferior) para saber cuáles son esos tipos de P, así como el tipo R de retorno exacto.
? (… args: p) => r: nunca? (… args: p) => r: nunca. Finalmente, completamos el tipo condicionado. Si F era una función, el tipo devuelto es una nueva función cuyos argumentos son del tipo P y cuyo tipo devuelto es r. Si no es así, el tipo de devolución no es nunca. Solo cómo podemos usar este tipo de ayuda para crear el nuevo tipo:
Const getPost = (estado: estado, id: postid) => post | no afinado; OmitFirstarg == (id: postid) => post | no afinado; ¡Y ya estamos un paso más cerca de lograr lo que queremos! Aquí puedes ver este ejemplo en el patio de recreo. Cómo cambiar el tipo de retorno de un tipo de función en TypeScript Estoy seguro de que ya conoce la respuesta a través de Know: Necesitamos un tipo genérico auxiliar que tome un tipo de función y devuelva un nuevo tipo de función. Algo como: escriba removerettourtype = f extiende (… args: infer p) => ¿alguno? (… args: p) => void: nunca; Fácil, ¿verdad? Es bastante similar a lo que hemos hecho en la sección anterior: capturamos los tipos de Args en P (no necesitamos preguntar al menos un argumento X esta vez) e ignoramos el tipo de devolución. Si F es una función, devuelve una nueva función que devuelve nula. De lo contrario, nunca regresa. ¡Maravilloso!
Compruebe eso en el patio de recreo. Cómo mapear un tipo de objeto con otro tipo de objeto en TypeScript Nuestras acciones y nuestros selectores son dos objetos cuyas teclas son los nombres de esas acciones y selectores y cuyos valores son las funciones en sí. Esto significa que los tipos de estos objetos se ven así: selectores typeof === {getPost: (estado: estado, id: postid) => post | no afinado; GetPostsInday: (Estado: Estado, Día: Día) => PostId []; } Typeof Actions === {RecedgeWeWpost: (post: post) => recibeVnewPostction; UpdatePost: (postID: postid, atributos: parcial ) => updatePostction; } En las dos secciones anteriores aprendimos a convertir un tipo de función en otro tipo de función. Esto significa que podríamos definir nuevos tipos manualmente, como sigue: type selectors = {getPost: omitFirstarg ; GetPostsInday: omitFirstarg ; }; Type Actions = {recibeVNewPost: RemverETournType ; UpdatePost: RemovereTourType ; }; Pero, por supuesto, esto no es sostenible en el tiempo: especificamos manualmente los nombres de las funciones en ambos tipos. Claramente, queremos asignar automáticamente las definiciones del tipo inicial de acciones y selectores a nuevos tipos. Así es como puede hacer esto en TypeScript: type omitFirstargs = {[k en KeyOf o]: OmitFirstarg ; } Type Removerecypes = {[k en KeyOf o]: removerethype ; } Esperamos que esto ya tenga sentido, pero de todos modos revelar rápidamente lo que hace el fragmento anterior: escriba omitfcerstargs . Creamos un nuevo tipo auxiliar genérico que adquiere un objeto.
El resultado es otro tipo de objeto (como lo muestra los aparatos {…}). [K In KeyOf O].No sabemos las claves exactas que tendrá el nuevo objeto, pero sabemos que deben ser las mismas claves que las incluidas en O.Así que esto es lo que decimos TypeScript: queremos todas las claves que son una tecla O
Y luego, para cada clave k, su tipo es omitfirstarg .Es decir, obtenemos el tipo original (A [k]) y lo convirtimos en el tipo deseado usando el tipo auxiliar que definimos (en este caso, omitfirstarg).
Finalmente, hacemos lo mismo con RemoverEtureTyPes y el tipo auxiliar de removereTureTurePe original.

Copyright statement: Unless otherwise noted, this article is Collected from the Internet, please keep the source of the article when reprinting.

Check Also

gkOVSBm5B8SgiXmo

Shopify vs WooCommerce – ¿Cuál es la mejor plataforma?(Comparación)

Shopify vs WooCommerce

Leave a Reply

Your email address will not be published. Required fields are marked *