Skip to content

Commit 8825b76

Browse files
committed
types: make Buffers into mongodb.Binary in lean result type to match runtime behavior
Fix Automattic#14902
1 parent 0752c5d commit 8825b76

File tree

3 files changed

+25
-4
lines changed

3 files changed

+25
-4
lines changed

test/types/schema.test.ts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,10 @@ import {
2020
Types,
2121
Query,
2222
model,
23-
ValidateOpts
23+
ValidateOpts,
24+
BufferToBinary
2425
} from 'mongoose';
26+
import { Binary } from 'mongodb';
2527
import { IsPathRequired } from '../../types/inferschematype';
2628
import { expectType, expectError, expectAssignable } from 'tsd';
2729
import { ObtainDocumentPathType, ResolvePathType } from '../../types/inferschematype';
@@ -917,7 +919,7 @@ async function gh12593() {
917919
expectType<Buffer | undefined | null>(doc2.x);
918920

919921
const doc3 = await Test.findOne({}).orFail().lean();
920-
expectType<Buffer | undefined | null>(doc3.x);
922+
expectType<Binary | undefined | null>(doc3.x);
921923

922924
const arrSchema = new Schema({ arr: [{ type: Schema.Types.UUID }] });
923925

@@ -1663,3 +1665,14 @@ async function gh14950() {
16631665
expectType<string>(doc.location!.type);
16641666
expectType<number[]>(doc.location!.coordinates);
16651667
}
1668+
1669+
async function gh14902() {
1670+
const def = {
1671+
image: { type: Buffer }
1672+
} as const;
1673+
const exampleSchema = new Schema(def);
1674+
const Test = model('Test', exampleSchema);
1675+
1676+
const doc = await Test.findOne().lean().orFail();
1677+
expectType<Binary | null | undefined>(doc.image);
1678+
}

types/index.d.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -706,6 +706,14 @@ declare module 'mongoose' {
706706
[K in keyof T]: FlattenProperty<T[K]>;
707707
};
708708

709+
export type BufferToBinary<T> = T extends object ? {
710+
[K in keyof T]: T[K] extends Buffer
711+
? mongodb.Binary
712+
: T[K] extends (Buffer | null | undefined)
713+
? mongodb.Binary | null | undefined
714+
: T[K];
715+
} : T;
716+
709717
/**
710718
* Separate type is needed for properties of union type (for example, Types.DocumentArray | undefined) to apply conditional check to each member of it
711719
* https://www.typescriptlang.org/docs/handbook/2/conditional-types.html#distributive-conditional-types
@@ -716,7 +724,7 @@ declare module 'mongoose' {
716724
? Types.DocumentArray<FlattenMaps<ItemType>> : FlattenMaps<T>;
717725

718726
export type actualPrimitives = string | boolean | number | bigint | symbol | null | undefined;
719-
export type TreatAsPrimitives = actualPrimitives | NativeDate | RegExp | symbol | Error | BigInt | Types.ObjectId | Buffer | Function;
727+
export type TreatAsPrimitives = actualPrimitives | NativeDate | RegExp | symbol | Error | BigInt | Types.ObjectId | Buffer | Function | mongodb.Binary;
720728

721729
export type SchemaDefinitionType<T> = T extends Document ? Omit<T, Exclude<keyof Document, '_id' | 'id' | '__v'>> : T;
722730

types/query.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ declare module 'mongoose' {
211211
type QueryOpThatReturnsDocument = 'find' | 'findOne' | 'findOneAndUpdate' | 'findOneAndReplace' | 'findOneAndDelete';
212212

213213
type GetLeanResultType<RawDocType, ResultType, QueryOp> = QueryOp extends QueryOpThatReturnsDocument
214-
? (ResultType extends any[] ? Require_id<FlattenMaps<RawDocType>>[] : Require_id<FlattenMaps<RawDocType>>)
214+
? (ResultType extends any[] ? Require_id<FlattenMaps<BufferToBinary<RawDocType>>>[] : Require_id<FlattenMaps<BufferToBinary<RawDocType>>>)
215215
: ResultType;
216216

217217
type MergePopulatePaths<RawDocType, ResultType, QueryOp, Paths, TQueryHelpers, TInstanceMethods = Record<string, never>> = QueryOp extends QueryOpThatReturnsDocument

0 commit comments

Comments
 (0)