[meteor]: Added OptionalId<T> to insert() method. Inspired by @types/mongo (#39933)

* Added OptionalId<T> 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.
This commit is contained in:
Chiciuc Nicușor 2019-10-30 17:07:39 +02:00 committed by Jesse Trinity
parent e01bb1556b
commit cd09bfd5ce
5 changed files with 83 additions and 26 deletions

View File

@ -1,3 +1,6 @@
// Based on https://github.com/microsoft/TypeScript/issues/28791#issuecomment-443520161
declare type UnionOmit<T, K extends keyof any> = T extends T ? Pick<T, Exclude<keyof T, K>> : never;
declare module Mongo {
type BsonType = 1 | "double" |
@ -115,6 +118,7 @@ declare module Mongo {
$pop?: PartialMapTo<T, 1 | -1> & Dictionary<1 | -1>,
}
type OptionalId<TSchema> = UnionOmit<TSchema, '_id'> & { _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<T>, callback?: Function): string;
rawCollection(): any;
rawDatabase(): any;
remove(selector: Selector<T> | ObjectID | string, callback?: Function): number;

View File

@ -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, K extends keyof any> = T extends T ? Pick<T, Exclude<keyof T, K>> : never;
module Mongo {
type BsonType = 1 | "double" |
@ -117,6 +120,7 @@ declare module "meteor/mongo" {
$pop?: PartialMapTo<T, 1 | -1> & Dictionary<1 | -1>,
}
type OptionalId<TSchema> = UnionOmit<TSchema, '_id'> & { _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<T>, callback?: Function): string;
rawCollection(): any;
rawDatabase(): any;
remove(selector: Selector<T> | ObjectID | string, callback?: Function): number;

View File

@ -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;

View File

@ -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<RoomDAO>('rooms');
let Messages = new Mongo.Collection<MessageDAO>('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<ChatroomsDAO>("chatrooms");
Messages = new Mongo.Collection<MessagesDAO>("messages");
Messages = new Mongo.Collection<MessageDAO>("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<iPost> | Mongo.Collection<PostDAO> = new Mongo.Collection<PostDAO>("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<ListDAO>('Lists');
var Items = new Mongo.Collection<ListDAO>('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<PostDAO | iPost>;
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;
});

View File

@ -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<RoomDAO>('rooms');
let Messages = new Mongo.Collection<MessageDAO>('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<ChatroomsDAO>("chatrooms");
Messages = new Mongo.Collection<MessagesDAO>("messages");
Messages = new Mongo.Collection<MessageDAO>("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<iPost> | Mongo.Collection<PostDAO> = new Mongo.Collection<PostDAO>("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<ListDAO>('Lists');
var Items = new Mongo.Collection<ListDAO>('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<PostDAO | iPost>;
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;
});