From cd09bfd5cee37e68ad05659acb03c849e690de91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Chiciuc=20Nicu=C8=99or?= Date: Wed, 30 Oct 2019 17:07:39 +0200 Subject: [PATCH] [meteor]: Added OptionalId to insert() method. Inspired by @types/mongo (#39933) * Added OptionalId to insert method. Inspired by @types/mongo * Fix the tests. * Defined 'UnionOmit' in such a way that applying it to a union type would work. * Fix spelling error. --- types/meteor/globals/mongo.d.ts | 6 ++- types/meteor/mongo.d.ts | 6 ++- types/meteor/scripts/generate-globals | 3 ++ types/meteor/test/globals/meteor-tests.ts | 47 +++++++++++++++++------ types/meteor/test/meteor-tests.ts | 47 +++++++++++++++++------ 5 files changed, 83 insertions(+), 26 deletions(-) diff --git a/types/meteor/globals/mongo.d.ts b/types/meteor/globals/mongo.d.ts index d35669cea1..2b1a7d8ca9 100644 --- a/types/meteor/globals/mongo.d.ts +++ b/types/meteor/globals/mongo.d.ts @@ -1,3 +1,6 @@ +// Based on https://github.com/microsoft/TypeScript/issues/28791#issuecomment-443520161 +declare type UnionOmit = T extends T ? Pick> : never; + declare module Mongo { type BsonType = 1 | "double" | @@ -115,6 +118,7 @@ declare module Mongo { $pop?: PartialMapTo & Dictionary<1 | -1>, } + type OptionalId = UnionOmit & { _id?: any }; interface SortSpecifier { } interface FieldSpecifier { @@ -159,7 +163,7 @@ declare module Mongo { reactive?: boolean; transform?: Function | null; }): T | undefined; - insert(doc: T, callback?: Function): string; + insert(doc: OptionalId, callback?: Function): string; rawCollection(): any; rawDatabase(): any; remove(selector: Selector | ObjectID | string, callback?: Function): number; diff --git a/types/meteor/mongo.d.ts b/types/meteor/mongo.d.ts index adb9644e3a..0659b1dfe8 100644 --- a/types/meteor/mongo.d.ts +++ b/types/meteor/mongo.d.ts @@ -1,5 +1,8 @@ import { Meteor } from 'meteor/meteor'; declare module "meteor/mongo" { + // Based on https://github.com/microsoft/TypeScript/issues/28791#issuecomment-443520161 + type UnionOmit = T extends T ? Pick> : never; + module Mongo { type BsonType = 1 | "double" | @@ -117,6 +120,7 @@ declare module "meteor/mongo" { $pop?: PartialMapTo & Dictionary<1 | -1>, } + type OptionalId = UnionOmit & { _id?: any }; interface SortSpecifier { } interface FieldSpecifier { @@ -161,7 +165,7 @@ declare module "meteor/mongo" { reactive?: boolean; transform?: Function | null; }): T | undefined; - insert(doc: T, callback?: Function): string; + insert(doc: OptionalId, callback?: Function): string; rawCollection(): any; rawDatabase(): any; remove(selector: Selector | ObjectID | string, callback?: Function): number; diff --git a/types/meteor/scripts/generate-globals b/types/meteor/scripts/generate-globals index d1cfc612e1..4acd75d8c3 100755 --- a/types/meteor/scripts/generate-globals +++ b/types/meteor/scripts/generate-globals @@ -67,6 +67,9 @@ for (let outFile of configObject.files) { return l; } else { let m2; + // Capture any line with a comment + if ((m2 = /^ (\/\/.*)$/.exec(l)) != null) return m2[1]; + if ((m2 = /^ ([^} ].*)$/.exec(l)) != null) return "declare " + m2[1]; if ((m2 = /^ (.*)$/.exec(l)) != null) return m2[1]; if (l == "") return l; diff --git a/types/meteor/test/globals/meteor-tests.ts b/types/meteor/test/globals/meteor-tests.ts index 3ed5e93830..648e160f09 100644 --- a/types/meteor/test/globals/meteor-tests.ts +++ b/types/meteor/test/globals/meteor-tests.ts @@ -14,8 +14,18 @@ // Avoid conflicts between `meteor-tests.ts` and `globals/meteor-tests.ts`. namespace MeteorTests { -var Rooms = new Mongo.Collection('rooms'); -var Messages = new Mongo.Collection('messages'); +interface RoomDAO { + _id: string; + name: string; +} + +interface MessageDAO { + _id: string; + text: string; +} + +const Rooms = new Mongo.Collection('rooms'); +let Messages = new Mongo.Collection('messages'); interface MonkeyDAO { _id: string; name: string; @@ -172,11 +182,9 @@ var result = Meteor.call('foo', 1, 2); interface ChatroomsDAO { _id?: string; } -interface MessagesDAO { - _id?: string; -} + var Chatrooms = new Mongo.Collection("chatrooms"); -Messages = new Mongo.Collection("messages"); +Messages = new Mongo.Collection("messages"); var myMessages: any[] = Messages.find({ userId: Session.get('myUserId') }).fetch(); @@ -184,7 +192,13 @@ Messages.insert({ text: "Hello, world!" }); Messages.update(myMessages[0]._id, { $set: { important: true } }); -var Posts = new Mongo.Collection("posts"); +interface PostDAO { + _id: string; + title: string; + body: string; +} + +var Posts : Mongo.Collection | Mongo.Collection = new Mongo.Collection("posts"); Posts.insert({ title: "Hello world", body: "First post" }); // Couldn't find assert() in the meteor docs @@ -223,9 +237,16 @@ Animals.findOne({ name: "raptor" }).makeNoise(); // prints "roar" /** * From Collections, Collection.insert section */ + +interface ListDAO { + _id: string; + list?: string; + name: string; +} + // DA: I added the variable declaration statements to make this work -var Lists = new Mongo.Collection('Lists'); -var Items = new Mongo.Collection('Lists'); +var Lists = new Mongo.Collection('Lists'); +var Items = new Mongo.Collection('Lists'); var groceriesId = Lists.insert({ name: "Groceries" }); Items.insert({ list: groceriesId, name: "Watercress" }); @@ -333,10 +354,12 @@ Posts.deny({ /** * From Collections, cursor.forEach section */ -var topPosts = Posts.find({}, { sort: { score: -1 }, limit: 5 }); +var topPosts = Posts.find({}, { sort: { score: -1 }, limit: 5 })as Mongo.Cursor; var count = 0; -topPosts.forEach(function (post: { title: string }) { - console.log("Title of post " + count + ": " + post.title); +topPosts.forEach(function (post) { + if ('title' in post) { + console.log("Title of post " + count + ": " + post.title); + } count += 1; }); diff --git a/types/meteor/test/meteor-tests.ts b/types/meteor/test/meteor-tests.ts index b7d6b68fd0..dd94e20ee2 100644 --- a/types/meteor/test/meteor-tests.ts +++ b/types/meteor/test/meteor-tests.ts @@ -26,8 +26,18 @@ import { DDPRateLimiter } from "meteor/ddp-rate-limiter"; // Avoid conflicts between `meteor-tests.ts` and `globals/meteor-tests.ts`. namespace MeteorTests { -var Rooms = new Mongo.Collection('rooms'); -var Messages = new Mongo.Collection('messages'); +interface RoomDAO { + _id: string; + name: string; +} + +interface MessageDAO { + _id: string; + text: string; +} + +const Rooms = new Mongo.Collection('rooms'); +let Messages = new Mongo.Collection('messages'); interface MonkeyDAO { _id: string; name: string; @@ -184,11 +194,9 @@ var result = Meteor.call('foo', 1, 2); interface ChatroomsDAO { _id?: string; } -interface MessagesDAO { - _id?: string; -} + var Chatrooms = new Mongo.Collection("chatrooms"); -Messages = new Mongo.Collection("messages"); +Messages = new Mongo.Collection("messages"); var myMessages: any[] = Messages.find({ userId: Session.get('myUserId') }).fetch(); @@ -196,7 +204,13 @@ Messages.insert({ text: "Hello, world!" }); Messages.update(myMessages[0]._id, { $set: { important: true } }); -var Posts = new Mongo.Collection("posts"); +interface PostDAO { + _id: string; + title: string; + body: string; +} + +var Posts : Mongo.Collection | Mongo.Collection = new Mongo.Collection("posts"); Posts.insert({ title: "Hello world", body: "First post" }); // Couldn't find assert() in the meteor docs @@ -235,9 +249,16 @@ Animals.findOne({ name: "raptor" }).makeNoise(); // prints "roar" /** * From Collections, Collection.insert section */ + +interface ListDAO { + _id: string; + list?: string; + name: string; +} + // DA: I added the variable declaration statements to make this work -var Lists = new Mongo.Collection('Lists'); -var Items = new Mongo.Collection('Lists'); +var Lists = new Mongo.Collection('Lists'); +var Items = new Mongo.Collection('Lists'); var groceriesId = Lists.insert({ name: "Groceries" }); Items.insert({ list: groceriesId, name: "Watercress" }); @@ -345,10 +366,12 @@ Posts.deny({ /** * From Collections, cursor.forEach section */ -var topPosts = Posts.find({}, { sort: { score: -1 }, limit: 5 }); +var topPosts = Posts.find({}, { sort: { score: -1 }, limit: 5 })as Mongo.Cursor; var count = 0; -topPosts.forEach(function (post: { title: string }) { - console.log("Title of post " + count + ": " + post.title); +topPosts.forEach(function (post) { + if ('title' in post) { + console.log("Title of post " + count + ": " + post.title); + } count += 1; });