jakearchibald / idb

IndexedDB, but with promises
https://www.npmjs.com/package/idb
ISC License
6.2k stars 348 forks source link

TS declaration error: Type 'IndexNames<DBTypes, StoreName>' does not satisfy the constraint 'string' #311

Open sumbricht opened 2 months ago

sumbricht commented 2 months ago

When compiling any project that relies on the idb library, I'm getting the following TypeScript error: Error: node_modules/idb/build/entry.d.ts:359:45 - error TS2344: Type 'IndexNames<DBTypes, StoreName>' does not satisfy the constraint 'string'

Looking at entry.d.ts, this error is actually correct. The error occurs in the property definition of indexNames:

export interface IDBPObjectStore<DBTypes extends DBSchema | unknown = unknown, StoreName extends StoreNames<DBTypes> = StoreNames<DBTypes>, Mode extends IDBTransactionMode = 'readonly'> extends IDBPObjectStoreExtends {
    readonly indexNames: TypedDOMStringList<IndexNames<DBTypes, StoreName>>;
    [..]
}

TypesDOMStringList<T extends string>expects IndexedNames to be of assignable to string but this turns out to be string | number due to the way IndexedNames is defined. The expression keyof DBTypes[StoreName]['indexes'] is unfortunately string | number even if it should intuitively be string only.

To verify this, let's look at a simplified example:

interface KeyValue {
    [s: string]: any;
}
type Key = keyof KeyValue // you'd expect `string` here, but it's `string | number`

To solve the problem, I propose changing the type IndexNames from export declare type IndexNames<DBTypes extends DBSchema | unknown, StoreName extends StoreNames<DBTypes>> = DBTypes extends DBSchema ? keyof DBTypes[StoreName]['indexes'] : string; to export declare type IndexNames<DBTypes extends DBSchema | unknown, StoreName extends StoreNames<DBTypes>> = DBTypes extends DBSchema ? keyof DBTypes[StoreName]['indexes'] & string : string;

As it's a very quick fix it may be easier for you to just do it; if you'd like a PR, just let me know :-).

Thanks a lot for your help and the great work on this library!

caboodal commented 2 months ago

I'm also getting this issue but only after upgrading typescript to 5.4.5 from 5.2.2: -

X [ERROR] TS2344: Type 'IndexNames<DBTypes, StoreName>' does not satisfy the constraint 'string'. Type 'string | number' is not assignable to type 'string'. Type 'number' is not assignable to type 'string'. [plugin angular-compiler]

node_modules/idb/build/entry.d.ts:359:44:
  359 │ ...y indexNames: TypedDOMStringList<IndexNames<DBTypes, StoreName>>;
philkunz commented 1 month ago

+1

simondingle commented 1 month ago

+1

philkunz commented 1 month ago

"@tempfix/idb": "^8.0.3" solves the problem for now by implementing the fix suggested above.

Metal-Mantis-Studio commented 1 month ago

+1