Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

472
Views
Vue 3 con inyección de mecanografiado no funciona según lo previsto. Los tipos de pliegos solo se pueden crear a partir de tipos de objetos.

Vue 3 y TypeScript dan un error (ver más abajo) PERO solo cuando está presente el script lang="ts". ¿Alguien puede ayudar a explicar por qué inject en Vue 3 con la etiqueta Typescript no funciona?

 ERROR in src/components/global/HeaderMenu.vue:85:7 TS2698: Spread types may only be created from object types. 83 | const auth = inject('Auth'); 84 | return { > 85 | ...auth, | ^^^^^^^ 86 | }; 87 | }, 88 | });

Ejemplo de trabajo:

 <script> import { defineComponent } from 'vue'; import { inject } from 'vue'; export default defineComponent({ name: 'HeaderMenu', inject: ['Auth'], methods: { login() { this.Auth.loginWithRedirect(); }, logout() { this.Auth.logout(); this.$router.push({ path: '/' }); }, }, setup() { const auth = inject('Auth'); return { ...auth, }; }, }); </script>

Ejemplo que genera el error anterior:

 <script lang="ts"> import { defineComponent } from 'vue'; import { inject } from 'vue'; export default defineComponent({ name: 'HeaderMenu', inject: ['Auth'], methods: { login() { this.Auth.loginWithRedirect(); }, logout() { this.Auth.logout(); this.$router.push({ path: '/' }); }, }, setup() { const auth = inject('Auth'); return { ...auth, }; }, }); </script>

Principal.js

 import { createApp } from 'vue'; import App from './App.vue'; import router from './router'; // Auth Service import { Auth0 } from '@/auth'; import BootstrapVue3 from 'bootstrap-vue-3'; // Import Bootstrap an BootstrapVue CSS files (order is important) import 'bootstrap/dist/css/bootstrap.css'; import 'bootstrap-vue-3/dist/bootstrap-vue-3.css'; async function init() { const AuthPlugin = await Auth0.init({ onRedirectCallback: (appState) => { router.push(appState && appState.targetUrl ? appState.targetUrl : window.location.pathname); }, clientId: 'xxxx', domain: 'xxxx', audience: process.env.VUE_APP_AUTH0_AUDIENCE, redirectUri: window.location.origin, }); const app = createApp(App); app .use(AuthPlugin) .use(router) .use(BootstrapVue3) .mount('#app'); } init();

Ejemplo de auth.js

 import createAuth0Client, { Auth0Client, GetIdTokenClaimsOptions, GetTokenSilentlyOptions, GetTokenWithPopupOptions, LogoutOptions, RedirectLoginOptions, User } from '@auth0/auth0-spa-js' import {App, Plugin, computed, reactive, watchEffect} from 'vue' import {NavigationGuardWithThis} from "vue-router"; let client: Auth0Client; interface Auth0PluginState { loading: boolean, isAuthenticated: boolean; user: User | undefined, popupOpen: boolean; error: any } const state = reactive<Auth0PluginState>({ loading: true, isAuthenticated: false, user: {}, popupOpen: false, error: null, }) async function handleRedirectCallback() { state.loading = true; try { await client.handleRedirectCallback(); state.user = await client.getUser(); state.isAuthenticated = true; } catch (e) { state.error = e; } finally { state.loading = false; } } function loginWithRedirect(o: RedirectLoginOptions) { return client.loginWithRedirect(o); } function getIdTokenClaims(o: GetIdTokenClaimsOptions) { return client.getIdTokenClaims(o); } function getTokenSilently(o: GetTokenSilentlyOptions) { return client.getTokenSilently(o); } function getTokenWithPopup(o: GetTokenWithPopupOptions) { return client.getTokenWithPopup(o); } function logout(o: LogoutOptions) { return client.logout(o); } const authPlugin = { isAuthenticated: computed(() => state.isAuthenticated), loading: computed(() => state.loading), user: computed(() => state.user), getIdTokenClaims, getTokenSilently, getTokenWithPopup, handleRedirectCallback, loginWithRedirect, logout, } const routeGuard: NavigationGuardWithThis<undefined> = (to: any, from: any, next: any) => { const {isAuthenticated, loading, loginWithRedirect} = authPlugin; const verify = async () => { // If the user is authenticated, continue with the route if (isAuthenticated.value) { return next(); } // Otherwise, log in await loginWithRedirect({appState: {targetUrl: to.fullPath}}); } // If loading has already finished, check our auth state using `fn()` if (!loading.value) { return verify(); } // Watch for the loading property to change before we check isAuthenticated watchEffect(() => { if (!loading.value) { return verify(); } }) } interface Auth0PluginOptions { domain: string, clientId: string, audience: string, redirectUri: string, onRedirectCallback(appState: any): void } async function init(options: Auth0PluginOptions): Promise<Plugin> { client = await createAuth0Client({ // domain: process.env.VUE_APP_AUTH0_DOMAIN, // client_id: process.env.VUE_APP_AUTH0_CLIENT_KEY, domain: options.domain, client_id: options.clientId, audience: options.audience, redirect_uri: options.redirectUri, }); try { // If the user is returning to the app after authentication if ( window.location.search.includes('code=') && window.location.search.includes('state=') ) { // handle the redirect and retrieve tokens const {appState} = await client.handleRedirectCallback(); // Notify subscribers that the redirect callback has happened, passing the appState // (useful for retrieving any pre-authentication state) options.onRedirectCallback(appState); } } catch (e) { state.error = e; } finally { // Initialize our internal authentication state state.isAuthenticated = await client.isAuthenticated(); state.user = await client.getUser(); state.loading = false; } return { install: (app: App) => { app.provide('Auth', authPlugin); }, } } interface Auth0Plugin { init(options: Auth0PluginOptions): Promise<Plugin>; routeGuard: NavigationGuardWithThis<undefined> } export const Auth0: Auth0Plugin = { init, routeGuard }
over 4 years ago · Santiago Trujillo
2 answers
Answer question

0

Primero, creo que está haciendo algo mal con la forma en que usa inyectar (cf. https://v3.vuejs.org/guide/composition-api-provide-inject.html#using-inject ). Creo que puedes eliminar la propiedad de inyección.

Entonces no está claro cómo usa las propiedades de inyección (a través del objeto inyectado Auth o a través de las propiedades de propagación del objeto Auth).

Supongo que para corregir la verificación del tipo de mecanografiado configurando el tipo de propiedad inyectada en Auth0Plugin por ejemplo (pero primero deberá exportar la interfaz).

over 4 years ago · Santiago Trujillo Report

0

No hay forma de que un compilador determine el tipo de auth de la llamada inject(...) porque no puede asociarlo con la llamada provide(...) . Debe proporcionarse información de tipo.

El tipo authPlugin debe estar expuesto, por ejemplo:

 export type TAuthPlugin = typeof authPlugin;

Entonces debe proporcionarse para inject . Como regla general, las funciones como inject son genéricas:

 const auth = inject<TAuthPlugin>('Auth');
over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!