diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4c3499115..f310bdf84 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -25,10 +25,10 @@ jobs: - run: npm ci - name: Build Types run: npm run build:types - - name: Lint Types - run: npm run lint:types - name: Test Types run: npm run test:types + - name: Lint Types + run: npm run lint:types check-docs: name: Check Docs timeout-minutes: 5 diff --git a/src/CoreManager.ts b/src/CoreManager.ts index 9ee9697ba..dff47e32a 100644 --- a/src/CoreManager.ts +++ b/src/CoreManager.ts @@ -15,9 +15,6 @@ import type ParseConfig from './ParseConfig'; import type LiveQueryClient from './LiveQueryClient'; import type ParseSchema from './ParseSchema'; import type ParseInstallation from './ParseInstallation'; -import type ParseQuery from './ParseQuery'; -import type * as ParseOp from './ParseOp'; -import type ParseRole from './ParseRole'; type AnalyticsController = { track: (name: string, dimensions: { [key: string]: string }) => Promise, @@ -598,7 +595,7 @@ const CoreManager = { return config['HooksController']!; }, - setParseOp(op: typeof ParseOp) { + setParseOp(op: any) { config['ParseOp'] = op; }, @@ -606,35 +603,35 @@ const CoreManager = { return config['ParseOp']!; }, - setParseObject(object: typeof ParseObject) { + setParseObject(object: any) { config['ParseObject'] = object; }, - getParseObject(): ParseObject { + getParseObject() { return config['ParseObject']!; }, - setParseQuery(query: typeof ParseQuery) { + setParseQuery(query: any) { config['ParseQuery'] = query; }, - getParseQuery(): ParseQuery { + getParseQuery() { return config['ParseQuery']!; }, - setParseRole(role: typeof ParseRole) { + setParseRole(role: any) { config['ParseRole'] = role; }, - getParseRole(): ParseRole { + getParseRole() { return config['ParseRole']!; }, - setParseUser(user: typeof ParseUser) { + setParseUser(user: any) { config['ParseUser'] = user; }, - getParseUser(): ParseUser { + getParseUser() { return config['ParseUser']!; }, }; diff --git a/src/ParseObject.ts b/src/ParseObject.ts index 23c699524..f00be9eef 100644 --- a/src/ParseObject.ts +++ b/src/ParseObject.ts @@ -2385,7 +2385,7 @@ const DefaultController = { return Promise.resolve(target); }, - save(target: ParseObject | Array, options: RequestOptions): Promise | ParseFile> { + save(target: ParseObject | null | Array, options: RequestOptions): Promise | ParseFile> { const batchSize = options && options.batchSize ? options.batchSize : CoreManager.get('REQUEST_BATCH_SIZE'); const localDatastore = CoreManager.getLocalDatastore(); @@ -2452,11 +2452,11 @@ const DefaultController = { // Queue up tasks for each object in the batch. // When every task is ready, the API request will execute - const batchReturned = new resolvingPromise(); - const batchReady = []; - const batchTasks = []; + const batchReturned = resolvingPromise(); + const batchReady: ReturnType>[] = []; + const batchTasks: Promise[] = []; batch.forEach((obj, index) => { - const ready = new resolvingPromise(); + const ready = resolvingPromise(); batchReady.push(ready); const task = function () { ready.resolve(); diff --git a/src/__tests__/escape-test.js b/src/__tests__/escape-test.js index 11e6e07af..767d5723a 100644 --- a/src/__tests__/escape-test.js +++ b/src/__tests__/escape-test.js @@ -1,6 +1,6 @@ jest.autoMockOff(); -const escape = require('../escape.js').default; +const escape = require('../escape').default; describe('escape', () => { it('escapes special HTML characters', () => { diff --git a/src/arrayContainsObject.js b/src/arrayContainsObject.ts similarity index 96% rename from src/arrayContainsObject.js rename to src/arrayContainsObject.ts index 188d21cfa..3c4ba6188 100644 --- a/src/arrayContainsObject.js +++ b/src/arrayContainsObject.ts @@ -1,7 +1,3 @@ -/** - * @flow - */ - import CoreManager from './CoreManager'; import type ParseObject from './ParseObject'; diff --git a/src/canBeSerialized.js b/src/canBeSerialized.ts similarity index 98% rename from src/canBeSerialized.js rename to src/canBeSerialized.ts index 3923a3545..a109b9236 100644 --- a/src/canBeSerialized.js +++ b/src/canBeSerialized.ts @@ -1,7 +1,3 @@ -/** - * @flow - */ - import CoreManager from './CoreManager'; import ParseFile from './ParseFile'; import type ParseObject from './ParseObject'; diff --git a/src/decode.js b/src/decode.ts similarity index 94% rename from src/decode.js rename to src/decode.ts index c358437a0..fc4c876ca 100644 --- a/src/decode.js +++ b/src/decode.ts @@ -1,8 +1,4 @@ -/** - * @flow - */ import CoreManager from './CoreManager'; -import ParseACL from './ParseACL'; // eslint-disable-line no-unused-vars import ParseFile from './ParseFile'; import ParseGeoPoint from './ParseGeoPoint'; import ParsePolygon from './ParsePolygon'; diff --git a/src/encode.js b/src/encode.ts similarity index 93% rename from src/encode.js rename to src/encode.ts index 3bcba74f3..e5558400f 100644 --- a/src/encode.js +++ b/src/encode.ts @@ -1,7 +1,3 @@ -/** - * @flow - */ - import CoreManager from './CoreManager'; import ParseACL from './ParseACL'; import ParseFile from './ParseFile'; @@ -10,10 +6,10 @@ import ParsePolygon from './ParsePolygon'; import ParseRelation from './ParseRelation'; function encode( - value: mixed, + value: any, disallowObjects: boolean, forcePointers: boolean, - seen: Array, + seen: Array, offline: boolean ): any { const ParseObject = CoreManager.getParseObject(); @@ -57,7 +53,7 @@ function encode( if (isNaN(value)) { throw new Error('Tried to encode an invalid date.'); } - return { __type: 'Date', iso: (value: any).toJSON() }; + return { __type: 'Date', iso: (value as Date).toJSON() }; } if ( Object.prototype.toString.call(value) === '[object RegExp]' && @@ -84,10 +80,10 @@ function encode( } export default function ( - value: mixed, + value: any, disallowObjects?: boolean, forcePointers?: boolean, - seen?: Array, + seen?: Array, offline?: boolean ): any { return encode(value, !!disallowObjects, !!forcePointers, seen || [], offline); diff --git a/src/equals.js b/src/equals.ts similarity index 96% rename from src/equals.js rename to src/equals.ts index bbc731f04..08b4d42da 100644 --- a/src/equals.js +++ b/src/equals.ts @@ -3,7 +3,7 @@ import ParseACL from './ParseACL'; import ParseFile from './ParseFile'; import ParseGeoPoint from './ParseGeoPoint'; -export default function equals(a, b) { +export default function equals(a: any, b: any): boolean { const toString = Object.prototype.toString; if (toString.call(a) === '[object Date]' || toString.call(b) === '[object Date]') { const dateA = new Date(a); diff --git a/src/escape.js b/src/escape.ts similarity index 93% rename from src/escape.js rename to src/escape.ts index e4b101aee..e7e6308e7 100644 --- a/src/escape.js +++ b/src/escape.ts @@ -1,7 +1,3 @@ -/* - * @flow - */ - const encoded = { '&': '&', '<': '<', diff --git a/src/isRevocableSession.js b/src/isRevocableSession.ts similarity index 85% rename from src/isRevocableSession.js rename to src/isRevocableSession.ts index 5da2de5fb..75309509b 100644 --- a/src/isRevocableSession.js +++ b/src/isRevocableSession.ts @@ -1,7 +1,3 @@ -/** - * @flow - */ - export default function isRevocableSession(token: string): boolean { return token.indexOf('r:') > -1; } diff --git a/src/parseDate.js b/src/parseDate.ts similarity index 88% rename from src/parseDate.js rename to src/parseDate.ts index 04ff6ea7f..13e922619 100644 --- a/src/parseDate.js +++ b/src/parseDate.ts @@ -1,8 +1,4 @@ -/** - * @flow - */ - -export default function parseDate(iso8601: string): ?Date { +export default function parseDate(iso8601: string): Date | null { const regexp = new RegExp( '^([0-9]{1,4})-([0-9]{1,2})-([0-9]{1,2})' + 'T' + diff --git a/src/promiseUtils.js b/src/promiseUtils.ts similarity index 70% rename from src/promiseUtils.js rename to src/promiseUtils.ts index 176c32a0b..8e82a8191 100644 --- a/src/promiseUtils.js +++ b/src/promiseUtils.ts @@ -1,17 +1,18 @@ // Create Deferred Promise -export function resolvingPromise() { - let res; - let rej; - const promise = new Promise((resolve, reject) => { +export function resolvingPromise() { + let res: (value: T) => void; + let rej: (error: T) => void; + const promise = new Promise((resolve, reject) => { res = resolve; rej = reject; }); - promise.resolve = res; - promise.reject = rej; - return promise; + const defer: typeof promise & { resolve: (res: T) => void, reject: (err: any) => void } = promise as any; + defer.resolve = res!; + defer.reject = rej!; + return defer; } -export function when(promises) { +export function when(promises: any) { let objects; const arrayArgument = Array.isArray(promises); if (arrayArgument) { @@ -32,7 +33,7 @@ export function when(promises) { return Promise.resolve(returnValue); } - const promise = new resolvingPromise(); + const promise = resolvingPromise(); const resolveOne = function () { total--; @@ -45,7 +46,7 @@ export function when(promises) { } }; - const chain = function (object, index) { + const chain = function (object: Promise, index: number) { if (object && typeof object.then === 'function') { object.then( function (result) { @@ -70,7 +71,7 @@ export function when(promises) { return promise; } -export function continueWhile(test, emitter) { +export function continueWhile(test: () => any, emitter: () => Promise) { if (test()) { return emitter().then(() => { return continueWhile(test, emitter); diff --git a/src/unique.js b/src/unique.ts similarity index 81% rename from src/unique.js rename to src/unique.ts index 15bf6248b..fd31f74bf 100644 --- a/src/unique.js +++ b/src/unique.ts @@ -1,16 +1,12 @@ -/** - * @flow - */ - import arrayContainsObject from './arrayContainsObject'; import CoreManager from './CoreManager'; export default function unique(arr: Array): Array { - const uniques = []; + const uniques: T[] = []; arr.forEach(value => { const ParseObject = CoreManager.getParseObject(); if (value instanceof ParseObject) { - if (!arrayContainsObject(uniques, value)) { + if (!arrayContainsObject(uniques, value as typeof ParseObject)) { uniques.push(value); } } else { diff --git a/src/unsavedChildren.js b/src/unsavedChildren.ts similarity index 96% rename from src/unsavedChildren.js rename to src/unsavedChildren.ts index 3386e91c8..ce11d2966 100644 --- a/src/unsavedChildren.js +++ b/src/unsavedChildren.ts @@ -1,7 +1,3 @@ -/** - * @flow - */ - import CoreManager from './CoreManager'; import ParseFile from './ParseFile'; import type ParseObject from './ParseObject'; @@ -69,7 +65,7 @@ function traverse( return; } if (obj instanceof ParseFile) { - if (!obj.url() && encountered.files.indexOf(obj) < 0) { + if (!(obj as ParseFile).url() && encountered.files.indexOf(obj) < 0) { encountered.files.push(obj); } return; diff --git a/src/uuid.ts b/src/uuid.ts index 03be8a07e..1ba54b844 100644 --- a/src/uuid.ts +++ b/src/uuid.ts @@ -1,6 +1,6 @@ import { v4 } from 'uuid'; -let uuid: () => string = null as any; +let uuid: () => string; if (process.env.PARSE_BUILD === 'weapp') { uuid = function () { diff --git a/types/CoreManager.d.ts b/types/CoreManager.d.ts index 3dde6b121..dcf8cfcf4 100644 --- a/types/CoreManager.d.ts +++ b/types/CoreManager.d.ts @@ -286,13 +286,13 @@ declare const CoreManager: { getHooksController(): HooksController; setParseOp(op: any): void; getParseOp(): any; - setParseObject(object: typeof ParseObject): void; - getParseObject(): ParseObject; + setParseObject(object: any): void; + getParseObject(): any; setParseQuery(query: any): void; - getParseQuery(): ParseQuery; + getParseQuery(): any; setParseRole(role: any): void; - getParseRole(): ParseRole; + getParseRole(): any; setParseUser(user: any): void; - getParseUser(): ParseUser; + getParseUser(): any; }; export default CoreManager; diff --git a/types/arrayContainsObject.d.ts b/types/arrayContainsObject.d.ts index 764acda42..a6a357188 100644 --- a/types/arrayContainsObject.d.ts +++ b/types/arrayContainsObject.d.ts @@ -1,2 +1,2 @@ +import type ParseObject from './ParseObject'; export default function arrayContainsObject(array: Array, object: ParseObject): boolean; -import ParseObject from './ParseObject'; diff --git a/types/canBeSerialized.d.ts b/types/canBeSerialized.d.ts index 7cc2db046..fdf8e3775 100644 --- a/types/canBeSerialized.d.ts +++ b/types/canBeSerialized.d.ts @@ -1,2 +1,2 @@ +import type ParseObject from './ParseObject'; export default function canBeSerialized(obj: ParseObject): boolean; -import ParseObject from './ParseObject'; diff --git a/types/encode.d.ts b/types/encode.d.ts index 510cff8d7..d63c1e75a 100644 --- a/types/encode.d.ts +++ b/types/encode.d.ts @@ -1 +1 @@ -export default function _default(value: mixed, disallowObjects?: boolean, forcePointers?: boolean, seen?: Array, offline?: boolean): any; +export default function (value: any, disallowObjects?: boolean, forcePointers?: boolean, seen?: Array, offline?: boolean): any; diff --git a/types/isRevocableSession.d.ts b/types/isRevocableSession.d.ts index 29d483cbb..f85d82130 100644 --- a/types/isRevocableSession.d.ts +++ b/types/isRevocableSession.d.ts @@ -1,4 +1 @@ -/** - * @flow - */ export default function isRevocableSession(token: string): boolean; diff --git a/types/parseDate.d.ts b/types/parseDate.d.ts index 4ec986b68..45630f59e 100644 --- a/types/parseDate.d.ts +++ b/types/parseDate.d.ts @@ -1,4 +1 @@ -/** - * @flow - */ export default function parseDate(iso8601: string): Date | null; diff --git a/types/promiseUtils.d.ts b/types/promiseUtils.d.ts index ae6efac22..e652712a0 100644 --- a/types/promiseUtils.d.ts +++ b/types/promiseUtils.d.ts @@ -1,3 +1,9 @@ -export function resolvingPromise(): Promise; -export function when(promises: any, ...args: any[]): any; -export function continueWhile(test: any, emitter: any): any; +export declare function resolvingPromise(): Promise & { + resolve: (res: T) => void; + reject: (err: any) => void; +}; +export declare function when(promises: any): Promise | (Promise & { + resolve: (res: any) => void; + reject: (err: any) => void; +}); +export declare function continueWhile(test: () => any, emitter: () => Promise): any; diff --git a/types/unique.d.ts b/types/unique.d.ts index 1736d2e04..c305608cf 100644 --- a/types/unique.d.ts +++ b/types/unique.d.ts @@ -1 +1 @@ -export default function unique(arr: T[]): T[]; +export default function unique(arr: Array): Array; diff --git a/types/unsavedChildren.d.ts b/types/unsavedChildren.d.ts index ec1be90ca..57881ba36 100644 --- a/types/unsavedChildren.d.ts +++ b/types/unsavedChildren.d.ts @@ -1,3 +1,5 @@ +import ParseFile from './ParseFile'; +import type ParseObject from './ParseObject'; /** * Return an array of unsaved children, which are either Parse Objects or Files. * If it encounters any dirty Objects without Ids, it will throw an exception. @@ -7,5 +9,3 @@ * @returns {Array} */ export default function unsavedChildren(obj: ParseObject, allowDeepUnsaved?: boolean): Array; -import ParseObject from './ParseObject'; -import ParseFile from './ParseFile';