typescript NestJS装饰器不是函数类型错误

wlzqhblo  于 2023-05-08  发布在  TypeScript
关注(0)|答案(1)|浏览(151)

我正在使用NestJS构建API。
我将Redis添加到混合中,并创建了一个动态模块来创建一个redis连接。
然后我添加了装饰器来访问redis连接。
我的问题。我可以在其他服务中访问装饰器。
但是如果我试图在与装饰器在同一个文件夹中的模块中访问它,我会得到一个TypeError

@InjectRedisGraph(MainGraph) private readonly graph: Graph,
                     ^
TypeError: (0 , redis_graph_connection_decorator_1.InjectRedisGraph) is not a function

我所尝试的

  • 为导入设置绝对路径和相对路径,均失败
  • 导出了一个通用的console.log函数,该函数工作并被执行
  • 将模块标记为@Injetable,不起作用(尽管Injectable装饰器没有抛出TypeError)
  • 移动到模块文件的声明工程,但我希望文件是分开的

查看编译后的js,decorator的导出看起来很好。
VS Code可以解析所有的类/函数。
tsc在转译时不抛出任何错误。
所有配置都是默认的NestJS配置文件。
我希望这只是我的疏忽。我对NestJS和Typescript Decoratos非常陌生,但我现在有点迷路了。

  • 代码:* decorator
import { Inject } from '@nestjs/common'
import { RedisClientIdentifier } from './redis-graph-connection.provider'

/**
 * Simple decorator to make usage of graphredis more verbose
 */
export const InjectRedisGraph = (graph: symbol): ParameterDecorator => {
  return Inject(graph)
}

export function doesExport() {
  console.log("It does")
}

模组

import { DynamicModule, Logger, OnApplicationShutdown } from '@nestjs/common'
import { createRedisGraphProviders } from './redis-graph-connection.provider'
import { RedisClientOptions } from '@redis/client'
import { doesExport, InjectRedisGraph } from './redis-graph-connection.decorator'
import { MainGraph } from '../redis-store.constants'
import { Graph } from '@redis/graph'

export class RedisGraphModule implements OnApplicationShutdown {
  static logger = new Logger('redis-graph-client')

  static async forRootAsync(
    options: RedisGraphModuleOptions,
  ): Promise<DynamicModule> {
    const providers = await createRedisGraphProviders(options)
    return {
      module: RedisGraphModule,
      providers,
      exports: providers,
    }
  }

  //            |-> This throws TypeError, not a function
  constructor(@InjectRedisGraph(MainGraph) private readonly graph: Graph) {
    doesExport()
  }

  onApplicationShutdown() {
    // do some graph cleanup
  }
}

其他服务,这工作

import { Injectable, Logger } from '@nestjs/common'
import { EvidenceStore } from 'src/common/evidence-store.interface'
import { InjectRedisGraph } from 'src/redis-store/redis-graph-connection/redis-graph-connection.decorator'
import { MainGraph } from './redis-store.constants'
import { Graph } from '@redis/graph'

@Injectable()
export class RedisStore implements EvidenceStore {
  private readonly logger = new Logger('redis-graph-collector')

  constructor(
    @InjectRedisGraph(MainGraph) private readonly redisGraph: Graph,
  ) {}
...

redis-graph-connection.provider

import { createClient, Graph } from 'redis'
import { Provider } from '@nestjs/common'
import { RedisGraphModule, RedisGraphModuleOptions } from './redis-graph-connection.module'

export const RedisClientIdentifier = Symbol('redisClient')

export async function createRedisGraphProviders(
  options: RedisGraphModuleOptions,
): Promise<Array<Provider>> {
  const client = createClient(options.redisOptions)
  client.on('error', (err: Error) => {
    RedisGraphModule.logger.error(err.message, err.stack)
  })

  await client.connect()
  RedisGraphModule.logger.log('Connected')

  const providers: Array<Provider> = [
    {
      provide: RedisClientIdentifier,
      useValue: client,
    },
  ]

  options.graphs.forEach((graphName) => {
    providers.push({
      provide: graphName,
      useValue: new Graph(client, graphName.toString()),
    })
    RedisGraphModule.logger.log(`Created graph for ${graphName.toString()}`)
  })

  return providers
}
au9on6nz

au9on6nz1#

这里的主要问题是装饰器文件有一个循环文件导入模块文件。在运行时发生的情况是,这个循环导入让两个文件中的一个导出undefined,并在每个依赖项都被解决之后重新填充它。在调用decorator时(发生在文件导入时),依赖项仍然是undefined,您会得到此错误。循环导入是不确定的,这也是它有时有效有时无效的另一个原因

相关问题