node.js - Hur man separat typiserar Fastify-dekoratörer i olika plugins?


Jag har problem med att skriva dekoratörer i två plugins (områden):

import Fastify, { FastifyInstance } from 'fastify'
const fastify = Fastify()

// scope A
fastify.register((instance) => {
  instance.decorate('utilA', 'AAA')
  instance.get('/', (req, reply) => {
    const data = instance.utilA // Property 'utilA' does not exist on type 'FastifyInstance<...>'
    reply.send(data)
  })
}, { prefix: '/A/' })

// scope B
fastify.register((instance) => {
  instance.decorate('utilB', () => 'BBB')
  instance.get('/', (req, reply) => {
    const data = instance.utilB() // Property 'utilB' does not exist on type 'FastifyInstance<...>'
    reply.send(data)
  })
}, { prefix: '/B/' })

Jag kan definiera typer globalt:

declare module 'fastify' {
  interface FastifyInstance {
    utilA: string
    utilB: () => string
  }
}

Och det löser kompilatorfelen. Men eftersom utilA och utilB är definierade globalt tillåter kompilatorn mig att använda utilB i scope A och tvärtom.

Finns det ett sätt att göra samma sak men oberoende per scope?

Svar #1

Nej, jag tror inte att detta är möjligt med declare module ''-syntaxen på grund av hur TypeScript fungerar (även om någon smartare än jag kanske kan lista ut hur).

En sak du kan göra är att skapa en subtyp av FastifyInstance med dina nya egenskaper (de måste vara valfria annars kan TypeScript bli arg på dig beroende på dina tsconfig-inställningar) och typa din plugins fastify-instans med den typen. Till exempel:

// Scope A
import { FastifyInstance } from 'fastify';

type MyPluginsFastifyInstance = FastifyInstance & { myThing?: MyType; }

export default async (fastify: MyPluginFastifyInstance) => {
  ... // Implementation.
  fastify.myThing // TypeScript is happy :)
}

// Scope B
export default async (fastify) => {
  fastify.myThing // TypeScript is mad at you >:(
}

Relaterade artiklar