Uploaded image for project: 'Couchbase node.js Client Library'
  1. Couchbase node.js Client Library
  2. JSCBC-1166

Provide type inference for sub-document operations

    XMLWordPrintable

Details

    • Improvement
    • Resolution: Duplicate
    • Minor
    • None
    • 4.2.4
    • library
    • 0

    Description

      The types could be improved a lot. Take the following exemple :

      type Book = {
        authors: string[];
        sales: [number, number],
      }
       
      const result = cb.collection('my_collection').lookupIn<Book>('foo', [
        LookupInSpec.get('authors'), <== 👌
        LookupInSpec.get('sales[3]'), <== Type Error
      ]);
      

      Which basically boils down to

      declare module 'couchbase' {
        class LookupInSpec<T> {
          static get<T = any>(path: DocumentPath<T> | LookupInMacro, options?: { xattr?: boolean; });
        }
       
        class Collection {
          lookupIn<T = any>(key: string, specs: LookupInSpec<T>[], options?: LookupInOptions, callback?: NodeCallback<LookupInResult>): Promise<LookupInResult>;
        }
      }
      

      With the following type definitions :

      type TupleIndices<T extends readonly unknown[]> = Exclude<Partial<T>['length'], T['length']> & number;
      type ArrayIndices<T extends readonly unknown[]> = number extends T['length']
        ? -1 | (number & {})
        : 0 extends TupleIndices<T> ? TupleIndices<T> | -1 : never;
       
      type AccessibleKey = string | number;
      type ArrayAccessor<T extends readonly unknown[], K extends AccessibleKey> = K extends ArrayIndices<T> ? `[${K}]` : never;
      type ObjectAccessor<K extends AccessibleKey, IsRoot extends boolean> = IsRoot extends true ? K : `.${K}`;
       
      type Accessor<T, K extends AccessibleKey, IsRoot extends boolean> =
        T extends readonly unknown[] ? ArrayAccessor<T, K> : ObjectAccessor<K, IsRoot>;
       
      export type DocumentPath<T, IsRoot extends boolean = true, K extends keyof T = keyof T> = K extends AccessibleKey
        ? `${Accessor<T, K, IsRoot>}${'' | (
          T[K] extends readonly unknown[]
            ? DocumentPath<T[K], false, ArrayIndices<T[K]>>
            : (T[K] extends object ? DocumentPath<T[K], false> : '')
          )}`
        : never
      

      I noticed the SDK is mostly autogenerated. Will this change in the future ?
      In order to fit the Node.JS culture it cannot rely on automated tasks...

      Attachments

        Issue Links

          No reviews matched the request. Check your Options in the drop-down menu of this sections header.

          Activity

            People

              jared.casey Jared Casey
              JesusTheHun Jonathan MASSUCHETTI
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Gerrit Reviews

                  There are no open Gerrit changes

                  PagerDuty