Home > Back-end >  String version of MongoDB WithID typescript generic
String version of MongoDB WithID typescript generic

Time:01-10

The WithId generic that comes with Mongo's typescript library is highly useful in scenarios where you don't want to modify your existing interface/type for use with MongoDB such as:

export class TagsCl {
    private publicTags: Promise<Array<WithId<ProductTag>>>;
    private allTags: Promise<Array<WithId<ProductTag>>>;
    private tags: Collection<ProductTag>;
        constructor(){
            //...
        }
        //...
}

I'd like a very similar generic called WithStrId or WithStringId or whatever that accomplishes the same thing, but adds a field with _id: string instead to an existing type/interface, for use in the front-end. What's the easiest way to make such a generic?

The existing WithId looks a bit complicated

/** TypeScript Omit (Exclude to be specific) does not work for objects with an "any" indexed type, and breaks discriminated unions @public */
export declare type EnhancedOmit<TRecordOrUnion, KeyUnion> = string extends keyof TRecordOrUnion ? TRecordOrUnion : TRecordOrUnion extends any ? Pick<TRecordOrUnion, Exclude<keyof TRecordOrUnion, KeyUnion>> : never;
export declare type InferIdType<TSchema> = TSchema extends {
    _id: infer IdType;
} ? Record<any, never> extends IdType ? never : IdType : TSchema extends {
    _id?: infer IdType;
} ? unknown extends IdType ? ObjectId : IdType : ObjectId;

export declare type WithId<TSchema> = EnhancedOmit<TSchema, '_id'> & {
    _id: InferIdType<TSchema>;
};

CodePudding user response:

Try

type WithStringId<Schema> = Schema extends {
  _id: string
} ? Schema : never

The never type will simply not be allowed by the compiler.

  • Related