Saltar al contenido principal
Versión: 11.x

Migrar de v10 a v11

Traducción Beta No Oficial

Esta página fue traducida por PageTurner AI (beta). No está respaldada oficialmente por el proyecto. ¿Encontraste un error? Reportar problema →

Migrando de v10 a v11

consejo

Para la mayoría de usuarios, la migración será rápida y sencilla.

Si los tres pasos siguientes no son suficientes, revisa el documento buscando "rarely breaking" (cambios que raramente rompen).

1. Instala las nuevas versiones

npm install @trpc/server@^11 @trpc/client@^11 @trpc/react-query@^11 @trpc/next@^11 @tanstack/react-query@^5 @tanstack/react-query-devtools@^5

Consulta los transformers se movieron a links para más información.

3. Si usas @trpc/react-query, actualiza tu versión de @tanstack/react-query

Consulta react-query-v5 para más información.

Changelog completo en orden cronológico inverso

¡Nueva integración con TanStack React Query! (no rompe cambios)

Nos complace anunciar que la nueva integración con TanStack React Query para tRPC ya está disponible en la versión next de tRPC.

Read the blog post for more information.

Detener suscripciones desde el servidor (raramente rompe cambios)

Ahora soportamos detener suscripciones desde el servidor, lo que permite hacer cosas como:

ts
const myRouter = router({
sub: publicProcedure.subscription(async function* (opts) {
for await (const data of on(ee, 'data', {
signal: opts.signal,
})) {
const num = data[0] as number | undefined;
if (num === undefined) {
// This will now stop the subscription on the client and trigger the `onComplete` callback
return;
}
yield num;
}
}),
});
ts
const myRouter = router({
sub: publicProcedure.subscription(async function* (opts) {
for await (const data of on(ee, 'data', {
signal: opts.signal,
})) {
const num = data[0] as number | undefined;
if (num === undefined) {
// This will now stop the subscription on the client and trigger the `onComplete` callback
return;
}
yield num;
}
}),
});

Consulta la documentación de suscripciones para más información.

Soporte añadido para routers de carga diferida (no rompe cambios)

Consulta la documentación de routers de carga diferida para más información.

Como parte de esto, cambiamos el argumento del método interno callProcedure() para recibir un parámetro { router: AnyRouter } en lugar de { _def: AnyRouter['_def'] }.

basePath personalizado para manejar solicitudes en el adaptador standalone (no rompe cambios)

El adaptador standalone ahora soporta una opción basePath, que recortará este prefijo del inicio de la ruta de solicitud.

Consulta la documentación del adaptador standalone para más información.

Soporte añadido para servidores HTTP/2 (no rompe cambios)

Ahora soportamos servidores HTTP/2, lo que permite usar las funciones createHTTP2Handler y createHTTPServer para crear servidores HTTP/2.

Consulta la documentación del adaptador standalone para más información.

Mover TRPCProcedureOptions a @trpc/client (no rompe cambios para la mayoría)

Si antes usabas ProcedureOptions de @trpc/server, ahora debes usar TRPCProcedureOptions de @trpc/client.

Permitir promesas anidadas en datos (no rompe cambios)

Ahora permitimos promesas anidadas en datos cuando se usa httpBatchStreamLink, lo que posibilita hacer:

ts
const router = router({
embedPromise: publicProcedure.query(() => {
async function slowThing() {
await new Promise((resolve) => setTimeout(resolve, 1000));
return 'slow';
}
return {
instant: 'instant',
slow: slowThing(),
};
}),
});
ts
const router = router({
embedPromise: publicProcedure.query(() => {
async function slowThing() {
await new Promise((resolve) => setTimeout(resolve, 1000));
return 'slow';
}
return {
instant: 'instant',
slow: slowThing(),
};
}),
});

Movido reconnectAfterInactivityMs a sse.client (no rompe cambios)

Actualizada la sección Mejoras en HTTP Subscription Link y documentación relacionada.

Ahora se requiere TypeScript versión >=5.7.2 (no rompe cambios)

tRPC ahora requiere TypeScript versión 5.7.2 o superior. Este cambio responde a un reporte de error donde adoptamos un enfoque orientado al futuro.

Si intentas instalar tRPC con una versión de TypeScript no compatible, recibirás un error de dependencia peer durante la instalación.

Si notas que tu editor muestra tipos any, probablemente se deba a que tu editor no está usando la versión correcta de TypeScript. Para solucionarlo, deberás configurar tu editor para que use la versión de TypeScript instalada en el package.json de tu proyecto.

Para usuarios de VSCode, añade esta configuración en tu .vscode/settings.json:

.vscode/settings.json
json
{
"typescript.tsdk": "node_modules/typescript/lib",
"typescript.enablePromptUseWorkspaceTsdk": true
}
.vscode/settings.json
json
{
"typescript.tsdk": "node_modules/typescript/lib",
"typescript.enablePromptUseWorkspaceTsdk": true
}

Cambio de experimental.sseSubscriptions a sse (no rompe)

La opción experimental.sseSubscriptions se ha movido a simplemente sse en la función initTRPC.create().

Se añadió soporte para detectar y recuperarse de conexiones obsoletas:

En el servidor, puedes configurar un intervalo de ping para mantener la conexión activa:

ts
export const t = initTRPC.create({
// ...
sse: {
ping: {
enabled: true,
intervalMs: 15_000,
},
client: {
// Reconnect if no messages or pings are received for 20 seconds
reconnectAfterInactivityMs: 20_000,
},
},
});
ts
export const t = initTRPC.create({
// ...
sse: {
ping: {
enabled: true,
intervalMs: 15_000,
},
client: {
// Reconnect if no messages or pings are received for 20 seconds
reconnectAfterInactivityMs: 20_000,
},
},
});

Probablemente añadiremos una configuración predeterminada de intervalo de ping y timeout en el futuro, pero esto aún no está decidido. Los comentarios son bienvenidos en el canal 🎏-rfc-streaming de Discord.

Consulta la documentación de httpSubscriptionLink para más detalles sobre estas características.

Consulta retryLink: permite reintentar operaciones fallidas.

Mejoras en useSubscription (no rompe)

  • Al suscribirse a procedimientos usando el hook useSubscription, ahora devolverá información sobre el estado de la suscripción y la conexión.

  • Posibilidad de usar un ponyfill con httpSubscriptionLink

El tipo de salida del procedimiento de suscripción cambió a AsyncGenerator (no rompe)

Si has usado suscripciones con generadores asíncronos en v11, esto podría romper tu forma de inferir tipos.

Details

We changed the inferred output from:

ts
SubscriptionProcedure<{
input: __INPUT__;
output: __OUTPUT__;
}>;
ts
SubscriptionProcedure<{
input: __INPUT__;
output: __OUTPUT__;
}>;

to

ts
SubscriptionProcedure<{
input: __INPUT__;
output: AsyncGenerator<__OUTPUT__, void, unknown>;
}>;
ts
SubscriptionProcedure<{
input: __INPUT__;
output: AsyncGenerator<__OUTPUT__, void, unknown>;
}>;

If you need to infer the value you can use a helper like the below:

ts
type inferAsyncIterableYield<TOutput> =
TOutput extends AsyncGenerator<infer $Yield> ? $Yield : never;
ts
type inferAsyncIterableYield<TOutput> =
TOutput extends AsyncGenerator<infer $Yield> ? $Yield : never;

Este cambio garantiza que la biblioteca siga siendo compatible con futuras actualizaciones y permite usar el tipo return en los AsyncGenerators de suscripciones.

Consulta la documentación de suscripciones para más información.

Se añadió soporte para validadores de salida en suscripciones (no rompe)

Consulta la documentación de suscripciones para más información.

Desaprobación de suscripciones que devuelven Observables (no rompe)

Ahora admitimos que las suscripciones devuelvan funciones generadoras asíncronas y previamente añadimos un httpSubscriptionLink.

Para ver cómo usar funciones generadoras asíncronas en suscripciones, consulta la documentación de suscripciones.

Eliminación del ponyfill AbortControllerEsque (rara vez rompe)

Hemos eliminado el ponyfill AbortControllerEsque de tRPC. Si necesitas soportar navegadores antiguos, puedes usar un polyfill como abortcontroller-polyfill.

Soporte para eventos enviados por el servidor (SSE) (no rompe)

Ahora admitimos SSE para suscripciones, lo que significa que no necesitas iniciar un servidor WebSocket para obtener actualizaciones en tiempo real en tu aplicación, y que el cliente puede reconectarse y reanudar automáticamente si se pierde la conexión.

👉 Consulta más en la documentación de httpSubscriptionLink.

Soporte para respuestas en streaming sobre HTTP (no rompe)

Ahora admitimos mutaciones y consultas en streaming mediante el enlace httpBatchStreamLink.

Esto significa que los resolvers de consultas y mutaciones pueden ser AsyncGenerators con yield o devolver promesas que pueden diferirse para más tarde, permitiendo respuestas en flujo sobre HTTP sin usar WebSockets.

¡Queremos tu opinión sobre esta función! Por favor pruébala y cuéntanos qué piensas en el canal 🎏-rfc-streaming de nuestro Discord.

👉 Ver más en la documentación de httpBatchStreamLink

resolveHTTPRequest ha sido reemplazada por resolveRequest que usa Fetch APIs (poco frecuente, rompe compatibilidad)

La función resolveHTTPRequest ha sido reemplazada por resolveRequest que utiliza Fetch API - Request/Response.

Este cambio rompe compatibilidad para adaptadores HTTP, pero no debería afectarte como usuario.

Si estás desarrollando un adaptador, revisa cómo funcionan nuestros adaptadores en el código y no dudes en pedir ayuda en nuestro Discord.

TRPCRequestInfo ha sido actualizada (poco frecuente, rompe compatibilidad)

Las entradas ahora se materializan de forma diferida cuando el procedimiento las requiere, lo que significa que el input y el tipo de procedimiento ya no están disponibles cuando tRPC llama a createContext.

Aún puedes acceder al input llamando a info.calls[index].getRawInput().

Todo el soporte experimental para form-data ha sido reemplazado (poco frecuente, rompe compatibilidad)

Esto solo te afecta si usaste las funciones experimentales de formdata

  • experimental_formDataLink - usa httpLink

  • experimental_parseMultipartFormData - ya no es necesario

  • experimental_isMultipartFormDataRequest - ya no es necesario

  • experimental_composeUploadHandlers - ya no es necesario

  • experimental_createMemoryUploadHandler - ya no es necesario

  • experimental_NodeOnDiskFile y experimental_createFileUploadHandler - no soportados en esta primera versión, abre un issue si necesitas mantener datos en disco

  • experimental_contentTypeHandlers - ya no es necesario, pero podría volver si la comunidad lo requiere para nuevos tipos de datos

Puedes ver el nuevo enfoque en examples/next-formdata

Se movieron Procedure._def._output_in / Procedure._def._input_in a Procedure._def.$types (no rompe compatibilidad)

Este cambio afecta los internos de tRPC, pero no debería afectarte como usuario.

No necesitas hacer nada, a menos que uses directamente Procedure._def._output_in o Procedure._def._input_in en tu código.

Comprobaciones explícitas de Content-Type (no rompe compatibilidad)

Ahora tenemos comprobaciones explícitas para la cabecera Content-Type en solicitudes POST. Si envías una solicitud con un Content-Type que no coincide con el esperado, recibirás un error 415 Unsupported Media Type.

Nuestros clientes tRPC ya envían cabeceras content-type, así que esto solo podría afectarte si llamas a tRPC manualmente.

Se agregó soporte para anulación de métodos (poco frecuente, rompe compatibilidad)

Te permite anular el método HTTP para procedimientos y enviarlos siempre con POST, superando limitaciones como la longitud máxima de URLs.

Cierra #3910

Se agregó soporte para consultas infinitas bidireccionales (no rompe compatibilidad)

Consulta useInfiniteQuery()

Añadido el helper inferProcedureBuilderResolverOptions<T> (no importante)

Añade un helper para inferir las opciones del resolver de un constructor de procedimientos. Es útil para crear funciones reutilizables en diferentes procedimientos.

Consulta la prueba aquí como referencia de uso

Los transformers se mueven a los links (cambio importante) -

TypeScript te guiará durante esta migración

Solo aplica si usas transformers de datos.

Ahora configuras los transformers de datos en el array links en lugar de al inicializar el cliente tRPC:

Donde tengas un HTTP Link, debes añadir transformer: superjson si usas transformers:

ts
httpBatchLink({
url: '/api/trpc',
transformer: superjson, // <-- add this
});
ts
httpBatchLink({
url: '/api/trpc',
transformer: superjson, // <-- add this
});
ts
createTRPCNext<AppRouter>({
// [..]
transformer: superjson, // <-- add this
});
ts
createTRPCNext<AppRouter>({
// [..]
transformer: superjson, // <-- add this
});

El modo SSR de @trpc/next ahora requiere un prepass helper con ssr: true (poco frecuente, cambio importante)

Esto corrige https://github.com/trpc/trpc/issues/5378 donde react-dom se importaba innecesariamente.

Consulta la documentación SSR

Añadido soporte para definiciones abreviadas de routers (no importante)

Consulta Combinar routers

ts
const appRouter = router({
// Shorthand plain object for creating a sub-router
nested1: {
proc: publicProcedure.query(() => '...'),
},
// Equivalent of:
nested2: router({
proc: publicProcedure.query(() => '...'),
}),
});
ts
const appRouter = router({
// Shorthand plain object for creating a sub-router
nested1: {
proc: publicProcedure.query(() => '...'),
},
// Equivalent of:
nested2: router({
proc: publicProcedure.query(() => '...'),
}),
});

Eliminados inferHandlerInput<T> y ProcedureArgs<T> (no importante para la mayoría)

Si estos tipos no significan nada en tu código, ignora este punto

Usa inferProcedureInput<TProcedure> y TRPCProcedureOptions en su lugar

Añadido useSuspenseQueries()

Consulta useSuspenseQueries

https://github.com/trpc/trpc/pull/5226

Refactorización de genéricos internos (poco frecuente, cambio importante)

Hemos reorganizado nuestros genéricos internos para mejorar su legibilidad (TODO: enlace al constructor de procedimientos)

React requiere ahora >=18.2.0 (poco frecuente, cambio importante)

Consulta su guía de migración: https://react.dev/blog/2022/03/08/react-18-upgrade-guide

Ahora se requiere NodeJS 18+ y navegadores modernos (poco frecuente, cambio importante)

Hemos añadido uso de FormData, File, Blob y ReadableStream. NodeJS 18 es ahora obligatorio, aunque los navegadores soportan esto hace años.

  • Capacidad de pasar una Promise en el callback url para cambios de ubicación durante despliegues

  • Nueva opción lazy que desconecta automáticamente el websocket sin solicitudes pendientes

rawInput en middleware ahora es getRawInput (poco frecuente, cambio importante)

Aunque internamente no cambiamos nada aún, esto permite soportar tipos de contenido distintos a JSON, una funcionalidad muy solicitada.

Tipos simplificados y salidas .d.ts

Las procedures en tu router ahora solo emiten su entrada y salida, mientras que antes también incluían el objeto de contexto completo para cada procedure, lo que generaba complejidad innecesaria en, por ejemplo, los archivos .d.ts.

La dependencia par de React Query es ahora v5 (cambio importante) -

Lo principal que tendrás que hacer es reemplazar varias instancias de isLoading por isPending

Consulta su guía de migración: https://tanstack.com/query/v5/docs/framework/react/guides/migrating-to-v5

Los nombres de exportación AbcProxyXyz se han renombrado a AbcXyz (non-breaking)

Los nombres proxy se debían a que v9 usaba los nombres AbcXyz, estos han sido eliminados y los proxy se han renombrado a los nombres sin proxy, por ejemplo:

  • createTRPCClient quedó obsoleto desde v9 y ahora se ha eliminado completamente. createTRPCProxyClient ha sido renombrado a createTRPCClient. createTRPCProxyClient ahora está marcado como obsoleto.

SSG Helpers (rara vez rompe)

  • createSSGHelpers era para v9 y ahora se ha eliminado. El equivalente en v10, createProxySSGHelpers, ha sido renombrado a createSSGHelpers.

  • createProxySSGHelpers ahora está obsoleto pero tiene un alias a createSSGHelpers para compatibilidad con versiones anteriores.

  • Se eliminó el tipo exportado CreateSSGHelpersOptions

El modo interop se ha eliminado (rara vez rompe) -

Hemos eliminado el modo interop de tRPC. Este era un modo que permitía tener un período de transición fácil de v9 a v10. Este modo nunca estuvo destinado a ser compatible a largo plazo y ahora lo hemos eliminado.