mirror of
https://github.com/gosticks/DefinitelyTyped.git
synced 2026-08-12 13:00:19 +00:00
Generics and typed attributes for Parse.Object and sub classes (#40429)
* parse: generics and typed attributes for Parse.Object and sub classes * parse: Fix dt-header tslint rule
This commit is contained in:
committed by
Pranav Senthilnathan
parent
4311598e93
commit
f7da07be7b
Vendored
+35
-17
@@ -1,6 +1,6 @@
|
||||
// Type definitions for parse 2.2.9
|
||||
// Type definitions for parse 2.9
|
||||
// Project: https://parseplatform.org/
|
||||
// Definitions by: Ullisen Media Group <http://ullisenmedia.com>
|
||||
// Definitions by: Ullisen Media Group <https://github.com/ullisenmedia>
|
||||
// David Poetzsch-Heffter <https://github.com/dpoetzsch>
|
||||
// Cedric Kemp <https://github.com/jaeggerr>
|
||||
// Flavio Negrão <https://github.com/flavionegrao>
|
||||
@@ -10,6 +10,8 @@
|
||||
// Alexandre Hétu Rivard <https://github.com/AlexandreHetu>
|
||||
// Diamond Lewis <https://github.com/dplewis>
|
||||
// Jong Eun Lee <https://github.com/yomybaby>
|
||||
// Colin Ulin <https://github.com/pocketcolin>
|
||||
// Robert Helms <https://github.com/rdhelms>
|
||||
// Julien Quere <https://github.com/jlnquere>
|
||||
// Yago Tomé <https://github.com/yagotome>
|
||||
// Thibault MOCELLIN <https://github.com/tybi>
|
||||
@@ -339,17 +341,17 @@ declare namespace Parse {
|
||||
*
|
||||
* Creates a new model with defined attributes.
|
||||
*/
|
||||
class Object extends BaseObject {
|
||||
class Object<T extends any = any> extends BaseObject {
|
||||
|
||||
id: string;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
attributes: any;
|
||||
attributes: T;
|
||||
cid: string;
|
||||
changed: boolean;
|
||||
className: string;
|
||||
|
||||
constructor(className?: string, options?: any);
|
||||
constructor(attributes?: string[], options?: any);
|
||||
constructor(className?: string, attributes?: T, options?: any);
|
||||
|
||||
static createWithoutData<T extends Object>(id: string): T;
|
||||
static destroyAll<T extends Object>(list: T[], options?: Object.DestroyAllOptions): Promise<T[]>;
|
||||
@@ -388,7 +390,7 @@ declare namespace Parse {
|
||||
fetch(options?: Object.FetchOptions): Promise<this>;
|
||||
fetchFromLocalDatastore(): Promise<this> | void;
|
||||
fetchWithInclude(keys: string | Array<string | Array<string>>, options?: RequestOptions): Promise<this>;
|
||||
get(attr: string): any | undefined;
|
||||
get<K extends Exclude<keyof T, symbol | number>>(attr: K): T[K];
|
||||
getACL(): ACL | undefined;
|
||||
has(attr: string): boolean;
|
||||
hasChanged(attr: string): boolean;
|
||||
@@ -407,11 +409,24 @@ declare namespace Parse {
|
||||
removeAll(attr: string, items: any): this | false;
|
||||
revert(): void;
|
||||
revert(...keys: string[]): void;
|
||||
save(attrs?: { [key: string]: any } | null, options?: Object.SaveOptions): Promise<this>;
|
||||
save(key: string, value: any, options?: Object.SaveOptions): Promise<this>;
|
||||
save(attrs: object, options?: Object.SaveOptions): Promise<this>;
|
||||
set(key: string, value: any, options?: Object.SetOptions): this | false;
|
||||
set(attrs: object, options?: Object.SetOptions): this | false;
|
||||
save(
|
||||
attrs?: Partial<T> | null,
|
||||
options?: Object.SaveOptions
|
||||
): Promise<this>;
|
||||
save<K extends keyof T>(
|
||||
key: K,
|
||||
value: T[K],
|
||||
options?: Object.SaveOptions
|
||||
): Promise<this>;
|
||||
set(
|
||||
attrs: Partial<T>,
|
||||
options?: Object.SetOptions
|
||||
): this | false;
|
||||
set<K extends keyof T>(
|
||||
key: K,
|
||||
value: T[K],
|
||||
options?: Object.SetOptions
|
||||
): this | false;
|
||||
setACL(acl: ACL, options?: SuccessFailureOptions): this | false;
|
||||
toPointer(): Pointer;
|
||||
unPin(): Promise<void>;
|
||||
@@ -452,7 +467,8 @@ declare namespace Parse {
|
||||
* Every Parse application installed on a device registered for
|
||||
* push notifications has an associated Installation object.
|
||||
*/
|
||||
class Installation extends Object {
|
||||
class Installation<T extends any = any> extends Object<T> {
|
||||
|
||||
badge: any;
|
||||
channels: string[];
|
||||
timeZone: any;
|
||||
@@ -713,7 +729,8 @@ subscription.on('close', () => {});
|
||||
* A Parse.Role is a local representation of a role persisted to the Parse
|
||||
* cloud.
|
||||
*/
|
||||
class Role extends Object {
|
||||
class Role<T extends any = any> extends Object<T> {
|
||||
|
||||
constructor(name: string, acl: ACL);
|
||||
|
||||
getRoles(): Relation<Role, Role>;
|
||||
@@ -722,7 +739,7 @@ subscription.on('close', () => {});
|
||||
setName(name: string, options?: SuccessFailureOptions): any;
|
||||
}
|
||||
|
||||
class Config extends Object {
|
||||
class Config<T extends any = any> extends Object<T> {
|
||||
static get(options?: SuccessFailureOptions): Promise<Config>;
|
||||
static current(): Config;
|
||||
static save(attr: any): Promise<Config>;
|
||||
@@ -731,7 +748,7 @@ subscription.on('close', () => {});
|
||||
escape(attr: string): any;
|
||||
}
|
||||
|
||||
class Session extends Object {
|
||||
class Session<T extends any = any> extends Object<T> {
|
||||
static current(): Promise<Session>;
|
||||
|
||||
getSessionToken(): string;
|
||||
@@ -747,7 +764,8 @@ subscription.on('close', () => {});
|
||||
* user specific methods, like authentication, signing up, and validation of
|
||||
* uniqueness.</p>
|
||||
*/
|
||||
class User extends Object {
|
||||
class User<T extends any = any> extends Object<T> {
|
||||
|
||||
static allowCustomUserClass(isAllowed: boolean): void;
|
||||
static become(sessionToken: string, options?: UseMasterKeyOption): Promise<User>;
|
||||
static current(): User | undefined;
|
||||
|
||||
@@ -678,3 +678,123 @@ async function test_schema() {
|
||||
|
||||
schema.update({ sessionToken: '' }).then(results => {});
|
||||
}
|
||||
|
||||
function test_generic_object() {
|
||||
// Test Parse.Object instantiation with no type assertion
|
||||
const objAny = new Parse.Object('TestObject')
|
||||
objAny.attributes.whatever // any
|
||||
objAny.attributes.createdAt // Date | undefined
|
||||
objAny.attributes.updatedAt // Date | undefined
|
||||
objAny.attributes.objectId // string | undefined
|
||||
objAny.attributes.ACL // Parse.ACL | undefined
|
||||
|
||||
// Test Parse.Object instantiation with manual type assertion
|
||||
const objWithTypedAttrs = new Parse.Object<{ example: string }>('TestObject')
|
||||
const exampleAttr = objWithTypedAttrs.attributes.example // string
|
||||
const exampleGet = objWithTypedAttrs.get('example') // string
|
||||
// const badAttr = objWithTypedAttrs.attributes.other // error
|
||||
|
||||
// Test Parse.Object instantiation with attributes
|
||||
const objWithAttrsAndOptions = new Parse.Object('TestObject', { example: 200 })
|
||||
const exampleAttrFromOptions = objWithAttrsAndOptions.attributes.example // number
|
||||
const exampleGetFromOptions = objWithAttrsAndOptions.get('example') // number
|
||||
// const badAttr2 = objWithAttrsAndOptions.attributes.other // error
|
||||
|
||||
}
|
||||
|
||||
function test_to_json_generic() {
|
||||
|
||||
const exampleObjAny = new Parse.Object('TestObject')
|
||||
const exampleJsonAny = exampleObjAny.toJSON() // Parse.Object.Attributes
|
||||
|
||||
const exampleObjTyped = new Parse.Object('TestObject', {
|
||||
exampleProp: false,
|
||||
regexProp: new RegExp(''),
|
||||
dateProp: new Date(),
|
||||
parseProp: new Parse.Object('nestedObject', {
|
||||
exampleProp: false,
|
||||
regexProp: new RegExp(''),
|
||||
dateProp: new Date(),
|
||||
parseProp2: new Parse.Object('nestedObject', {
|
||||
exampleProp2: false,
|
||||
regexProp2: new RegExp(''),
|
||||
dateProp2: new Date()
|
||||
})
|
||||
})
|
||||
})
|
||||
const exampleJsonTyped = exampleObjTyped.toJSON()
|
||||
exampleJsonTyped.exampleProp // boolean
|
||||
exampleJsonTyped.dateProp // string
|
||||
exampleJsonTyped.regexProp // string
|
||||
exampleJsonTyped.parseProp.dateProp // string
|
||||
exampleJsonTyped.parseProp.parseProp2.regexProp2 // string
|
||||
exampleJsonTyped.parseProp.ACL // Parse.ACL | undefined
|
||||
exampleJsonTyped.parseProp.objectId // string | undefined
|
||||
}
|
||||
|
||||
async function test_save_generic() {
|
||||
const exampleObjAny = new Parse.Object('TestObject')
|
||||
const savedAny = await exampleObjAny.save()
|
||||
savedAny.attributes.anything // any
|
||||
const savedNewExampleAttrAny = await exampleObjAny.save({ example: true })
|
||||
savedNewExampleAttrAny.attributes.anythingElse // any
|
||||
|
||||
// Calling Parse.Object.save({}) with an existing attribute type checks
|
||||
const exampleObjTyped = new Parse.Object<{ example: number; newExample: string }>('TestObject')
|
||||
// const badSavedExampleAttr = await exampleObjTyped.save({ example: 'hello' }) // error
|
||||
const savedExampleAttr = await exampleObjTyped.save({ example: 5 })
|
||||
savedExampleAttr.attributes.example // number
|
||||
|
||||
// const badSavedExampleAttr = await exampleObjTyped.save({ createdAt: new Date() }) // never
|
||||
|
||||
// Calling Parse.Object.save({}) with a new attribute adds that attribute as a known key
|
||||
const savedNewExampleAttr = await exampleObjTyped.save({ newExample: 'hello' })
|
||||
savedNewExampleAttr.attributes.example // number
|
||||
savedNewExampleAttr.attributes.newExample // string
|
||||
|
||||
// Parse.Object.save(key, value) type checks existing keys
|
||||
// const badSavedExampleAttr2 = await exampleObjTyped.save('example', 'hello') // error
|
||||
const savedExampleAttr2 = await exampleObjTyped.save('example', 10)
|
||||
savedExampleAttr2.attributes.example // number
|
||||
|
||||
// const badSavedExampleAttr2 = await exampleObjTyped.save('createdAt', 10) // never
|
||||
|
||||
// Parse.Object.save(key, value) with a new attribute adds that attribute as a known key
|
||||
const savedNewExampleAttr2 = await exampleObjTyped.save('newExample', 'hello again')
|
||||
savedNewExampleAttr2.attributes.example // number
|
||||
savedNewExampleAttr2.attributes.newExample // string
|
||||
}
|
||||
|
||||
function test_set_generic() {
|
||||
const exampleObjAny = new Parse.Object('TestObject')
|
||||
exampleObjAny.attributes // any
|
||||
exampleObjAny.set('propA', 'some value')
|
||||
|
||||
const exampleObjTyped = new Parse.Object<{ example: boolean }>('TestObject')
|
||||
|
||||
// Parse.Object.set({}) type checks existing keys, does not allow new keys
|
||||
const setThingObj = exampleObjTyped.set({ example: false })
|
||||
setThingObj && setThingObj.attributes.example // boolean
|
||||
// exampleObjTyped.set({ example: 100 }) // error
|
||||
// const badSetNewThingObj = exampleObjTyped.set({ newExample: 'something' }) // error
|
||||
|
||||
// Parse.Object.set(key, value) does not allow new keys
|
||||
const setThingKeyVal = exampleObjTyped.set('example', false)
|
||||
setThingKeyVal && setThingKeyVal.attributes.example // boolean
|
||||
// const badSetThingNewKeyVal = exampleObjTyped.set('newExample', 100) // error
|
||||
}
|
||||
|
||||
async function test_query_generic() {
|
||||
const exampleQuery = new Parse.Query<Parse.Object<{ example: string }>>('TestObject')
|
||||
|
||||
const gotExampleObj = await exampleQuery.get('objectId')
|
||||
const gotAttrExample = gotExampleObj.attributes.example // string
|
||||
const gotGetExample = gotExampleObj.get('example') // string
|
||||
// const badGotGetExample = gotExampleObj.get('anything') // error
|
||||
|
||||
const foundExampleObj = await exampleQuery.find()
|
||||
foundExampleObj[0] && foundExampleObj[0].attributes.example // string
|
||||
|
||||
const firstExampleObj = await exampleQuery.first()
|
||||
firstExampleObj && firstExampleObj.attributes.example // string
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
"ban-types": false,
|
||||
"callable-types": false,
|
||||
"comment-format": false,
|
||||
"dt-header": false,
|
||||
"npm-naming": false,
|
||||
"eofline": false,
|
||||
"export-just-namespace": false,
|
||||
|
||||
Reference in New Issue
Block a user