I m having a problem with my KV Cache I

I'm having a problem with my KV Cache. I get this error "this.kv.get is not a function" and I can't figure out why. Here is my implementation
import type { KVNamespace } from '@cloudflare/workers-types'

export type KVCacheInstanceType<T> = InstanceType<typeof KVCache<T>>

export class KVCache<T> {
private kv: KVNamespace
constructor(namespace: KVNamespace) {
this.kv = namespace
}
async get(key: string): Promise<T | null> {
try {
const value = await this.kv.get(key, 'text')
return value ? this.parseJson(value) : null
} catch (error) {
console.log(error)
return null
}
}

async set(key: string, value: T, ttl?: number): Promise<void> {
try {
const stringValue = this.stringifyJson(value)
const options = ttl ? { expirationTtl: ttl } : undefined
await this.kv.put(key, stringValue, options)
} catch (error) {
console.log(error)
return
}
}

async delete(key: string) {
...
}

private parseJson(value: string): T | null {
...
}

private stringifyJson(value: T): string {
...
}
}
// Usage
const cache = new KVCache<GooglePublicKeys>(config.namespace)
import type { KVNamespace } from '@cloudflare/workers-types'

export type KVCacheInstanceType<T> = InstanceType<typeof KVCache<T>>

export class KVCache<T> {
private kv: KVNamespace
constructor(namespace: KVNamespace) {
this.kv = namespace
}
async get(key: string): Promise<T | null> {
try {
const value = await this.kv.get(key, 'text')
return value ? this.parseJson(value) : null
} catch (error) {
console.log(error)
return null
}
}

async set(key: string, value: T, ttl?: number): Promise<void> {
try {
const stringValue = this.stringifyJson(value)
const options = ttl ? { expirationTtl: ttl } : undefined
await this.kv.put(key, stringValue, options)
} catch (error) {
console.log(error)
return
}
}

async delete(key: string) {
...
}

private parseJson(value: string): T | null {
...
}

private stringifyJson(value: T): string {
...
}
}
// Usage
const cache = new KVCache<GooglePublicKeys>(config.namespace)
I checked my NAMESPACE and when I console(this.kv) it matches what I setup in Cloudflare.
3 Replies
MBrimmer
MBrimmer13mo ago
I figured this out but my Typescript is still wrong I now access my Namespace from the env with the name passed as an environment variable like this
// @ts-ignore
const cache = new KVCache<GooglePublicKeys>(env[env.CLOUDFLARE_KV_NAMESPACE] as KVNamespace)
// @ts-ignore
const cache = new KVCache<GooglePublicKeys>(env[env.CLOUDFLARE_KV_NAMESPACE] as KVNamespace)
I have the env typed with an interface and the Namespace doesn't play well with that approach.
Unknown User
Unknown User13mo ago
Message Not Public
Sign In & Join Server To View
MBrimmer
MBrimmer13mo ago
Hey @MattD | WorkersKV Sorry, not sure how I missed your response. The issue is CLOUDFLARE_KV_NAMESPACE is a string that tells my application which namespace e.g. development-namespace or production-namespace and is defined at runtime not compile time. Cloudflare provides my namespace as defined by my wrangler config. So this is only a typescript issue now and I solved it like this.
namespace: env[
env.CLOUDFLARE_KV_NAMESPACE as keyof typeof env
] as unknown as KVNamespace
namespace: env[
env.CLOUDFLARE_KV_NAMESPACE as keyof typeof env
] as unknown as KVNamespace
Not sure if this is how other people are doing it, but it working for me right now. Thanks for getting back with me!
Want results from more Discord servers?
Add your server