Skip to content

Enable strictNullChecks #1159

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 24, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 11 additions & 10 deletions packages/firestore/src/api/database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -319,12 +319,12 @@ export class Firestore implements firestore.FirebaseFirestore, FirebaseService {

enableNetwork(): Promise<void> {
this.ensureClientConfigured();
return this._firestoreClient.enableNetwork();
return this._firestoreClient!.enableNetwork();
}

disableNetwork(): Promise<void> {
this.ensureClientConfigured();
return this._firestoreClient.disableNetwork();
return this._firestoreClient!.disableNetwork();
}

enablePersistence(settings?: _PersistenceSettings): Promise<void> {
Expand Down Expand Up @@ -597,7 +597,7 @@ export class Transaction implements firestore.Transaction {
} else if (doc instanceof Document) {
return new DocumentSnapshot(this._firestore, ref._key, doc, false);
} else {
fail('MaybeDocument is neither Document nor NoDocument');
throw fail('MaybeDocument is neither Document nor NoDocument');
}
});
}
Expand Down Expand Up @@ -1060,8 +1060,8 @@ export class DocumentReference implements firestore.DocumentReference {
}

get(options?: firestore.GetOptions): Promise<firestore.DocumentSnapshot> {
validateOptionNames('DocumentReference.get', options, ['source']);
if (options) {
validateOptionNames('DocumentReference.get', options, ['source']);
validateNamedOptionalPropertyEquals(
'DocumentReference.get',
'options',
Expand Down Expand Up @@ -1888,11 +1888,10 @@ export class QuerySnapshot implements firestore.QuerySnapshot {
docChanges(
options?: firestore.SnapshotListenOptions
): firestore.DocumentChange[] {
validateOptionNames('QuerySnapshot.docChanges', options, [
'includeMetadataChanges'
]);

if (options) {
validateOptionNames('QuerySnapshot.docChanges', options, [
'includeMetadataChanges'
]);
validateNamedOptionalType(
'QuerySnapshot.docChanges',
'boolean',
Expand All @@ -1901,7 +1900,9 @@ export class QuerySnapshot implements firestore.QuerySnapshot {
);
}

const includeMetadataChanges = options && options.includeMetadataChanges;
const includeMetadataChanges = !!(
options && options.includeMetadataChanges
);

if (includeMetadataChanges && this._snapshot.excludesMetadataChanges) {
throw new FirestoreError(
Expand Down Expand Up @@ -2030,7 +2031,7 @@ export class CollectionReference extends Query
'Document path must be a non-empty string'
);
}
const path = ResourcePath.fromString(pathString);
const path = ResourcePath.fromString(pathString!);
return DocumentReference.forPath(
this._query.path.child(path),
this.firestore
Expand Down
12 changes: 7 additions & 5 deletions packages/firestore/src/api/user_data_converter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -339,20 +339,22 @@ export class UserDataConverter {
fieldMask = new FieldMask(context.fieldMask);
fieldTransforms = context.fieldTransforms;
} else {
const validatedFieldPaths = [];
const validatedFieldPaths: FieldPath[] = [];

for (const stringOrFieldPath of fieldPaths) {
let fieldPath;
let fieldPath: FieldPath;

if (stringOrFieldPath instanceof ExternalFieldPath) {
fieldPath = stringOrFieldPath as ExternalFieldPath;
fieldPath = stringOrFieldPath._internalPath;
} else if (typeof stringOrFieldPath === 'string') {
fieldPath = fieldPathFromDotSeparatedString(
methodName,
stringOrFieldPath
);
} else {
fail('Expected stringOrFieldPath to be a string or a FieldPath');
throw fail(
'Expected stringOrFieldPath to be a string or a FieldPath'
);
}

if (!context.contains(fieldPath)) {
Expand Down Expand Up @@ -693,7 +695,7 @@ export class UserDataConverter {
methodName,
FieldPath.EMPTY_PATH
);
return this.parseData(element, context.childContextForArray(i));
return this.parseData(element, context.childContextForArray(i))!;
});
}
}
Expand Down
2 changes: 1 addition & 1 deletion packages/firestore/src/core/firestore_client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -508,7 +508,7 @@ export class FirestoreClient {
return view.applyChanges(
viewDocChanges,
/* updateLimboDocuments= */ false
).snapshot;
).snapshot!;
});
}

Expand Down
5 changes: 3 additions & 2 deletions packages/firestore/src/core/query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -591,7 +591,8 @@ export class NanFilter extends Filter {
}

matches(doc: Document): boolean {
const val = doc.field(this.field).value();
const field = doc.field(this.field);
const val = field && field.value();
return typeof val === 'number' && isNaN(val);
}

Expand Down Expand Up @@ -680,7 +681,7 @@ export class Bound {
docValue !== undefined,
'Field should exist since document matched the orderBy already.'
);
comparison = component.compareTo(docValue);
comparison = component.compareTo(docValue!);
}
if (orderByComponent.dir === Direction.DESCENDING) {
comparison = comparison * -1;
Expand Down
15 changes: 8 additions & 7 deletions packages/firestore/src/core/sync_engine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ export class SyncEngine implements RemoteSyncer, SharedClientStateSyncer {
);
const viewChange = view.applyChanges(
viewDocChanges,
/* updateLimboDocuments= */ this.isPrimary,
/* updateLimboDocuments= */ this.isPrimary === true,
synthesizedTargetChange
);
assert(
Expand Down Expand Up @@ -781,7 +781,7 @@ export class SyncEngine implements RemoteSyncer, SharedClientStateSyncer {
remoteEvent && remoteEvent.targetChanges[queryView.targetId];
const viewChange = queryView.view.applyChanges(
viewDocChanges,
/* updateLimboDocuments= */ this.isPrimary,
/* updateLimboDocuments= */ this.isPrimary === true,
targetChange
);
return this.updateTrackedLimbos(
Expand Down Expand Up @@ -809,7 +809,7 @@ export class SyncEngine implements RemoteSyncer, SharedClientStateSyncer {
});

await Promise.all(queriesProcessed);
this.syncEngineListener.onWatchChange(newSnaps);
this.syncEngineListener!.onWatchChange(newSnaps);
this.localStore.notifyLocalViewChanges(docChangesInAllViews);
// TODO(multitab): Multitab garbage collection
if (this.isPrimary) {
Expand Down Expand Up @@ -940,13 +940,14 @@ export class SyncEngine implements RemoteSyncer, SharedClientStateSyncer {
}
} else {
assert(
this.isPrimary,
this.isPrimary === true,
'A secondary tab should never have an active query without an active view.'
);
// For queries that never executed on this client, we need to
// allocate the query in LocalStore and initialize a new View.
const query = await this.localStore.getQueryForTarget(targetId);
queryData = await this.localStore.allocateQuery(query);
assert(!!query, `Query data for target ${targetId} not found`);
queryData = await this.localStore.allocateQuery(query!);
await this.initializeViewAndComputeSnapshot(
queryData,
/*current=*/ false
Expand Down Expand Up @@ -1000,7 +1001,7 @@ export class SyncEngine implements RemoteSyncer, SharedClientStateSyncer {
queryView.query,
/*keepPersistedQueryData=*/ true
);
this.syncEngineListener!.onWatchError(queryView.query, error);
this.syncEngineListener!.onWatchError(queryView.query, error!);
break;
}
default:
Expand All @@ -1025,7 +1026,7 @@ export class SyncEngine implements RemoteSyncer, SharedClientStateSyncer {
);
const query = await this.localStore.getQueryForTarget(targetId);
assert(!!query, `Query data for active target ${targetId} not found`);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we could add an assertNotNull type guard that that would make the ! below unnecessary.

Something like:

assertNotNull<T>(value : T | null, explanation: string): arg is T {
  assert(!!value, explanation);
  return true;
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since these type guards only work in if-statements, this would change the calling site to:

  if (assertNotNull(query, `Query data for active target ${targetId} not found`)) {
        const queryData = await this.localStore.allocateQuery(query);
        await this.initializeViewAndComputeSnapshot(
            queryData,
            /*current=*/ false
        );
        this.remoteStore.listen(queryData);
      };

If we didn't have to put the explanation, then I would be all in favor. But with the explanation this looks a tad strange. If we do drop the explanation, we will never be able to trace these asserts back in minified code.

const queryData = await this.localStore.allocateQuery(query);
const queryData = await this.localStore.allocateQuery(query!);
await this.initializeViewAndComputeSnapshot(
queryData,
/*current=*/ false
Expand Down
8 changes: 5 additions & 3 deletions packages/firestore/src/local/indexeddb_mutation_queue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,9 @@ export class IndexedDbMutationQueue implements MutationQueue {
batchId: BatchId
): PersistencePromise<DocumentKeySet | null> {
if (this.documentKeysByBatchId[batchId]) {
return PersistencePromise.resolve(this.documentKeysByBatchId[batchId]);
return PersistencePromise.resolve<DocumentKeySet | null>(
this.documentKeysByBatchId[batchId]
);
} else {
return this.lookupMutationBatch(transaction, batchId).next(batch => {
if (batch) {
Expand Down Expand Up @@ -324,7 +326,7 @@ export class IndexedDbMutationQueue implements MutationQueue {
.get(batchId)
.next(mutation => {
if (!mutation) {
fail(
throw fail(
'Dangling document-mutation reference found: ' +
indexKey +
' which points to ' +
Expand Down Expand Up @@ -454,7 +456,7 @@ export class IndexedDbMutationQueue implements MutationQueue {
.get(batchId)
.next(mutation => {
if (mutation === null) {
fail(
throw fail(
'Dangling document-mutation reference found, ' +
'which points to ' +
batchId
Expand Down
20 changes: 11 additions & 9 deletions packages/firestore/src/local/indexeddb_persistence.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,9 @@ export class IndexedDbPersistence implements Persistence {
if (txn instanceof IndexedDbTransaction) {
return SimpleDb.getStore<Key, Value>(txn.simpleDbTransaction, store);
} else {
fail('IndexedDbPersistence must use instances of IndexedDbTransaction');
throw fail(
'IndexedDbPersistence must use instances of IndexedDbTransaction'
);
}
}

Expand Down Expand Up @@ -215,7 +217,7 @@ export class IndexedDbPersistence implements Persistence {
this.dbName = persistenceKey + IndexedDbPersistence.MAIN_DATABASE;
this.serializer = new LocalSerializer(serializer);
this.document = platform.document;
this.window = platform.window;
this.window = platform.window!;
this.allowTabSynchronization = synchronizeTabs;
this.queryCache = new IndexedDbQueryCache(this.serializer);
this.remoteDocumentCache = new IndexedDbRemoteDocumentCache(
Expand Down Expand Up @@ -354,7 +356,7 @@ export class IndexedDbPersistence implements Persistence {
this.lastGarbageCollectionTime = Date.now();

let activeClients: DbClientMetadata[];
let inactiveClients: DbClientMetadata[];
let inactiveClients: DbClientMetadata[] = [];

await this.runTransaction('readwrite', true, txn => {
const metadataStore = IndexedDbPersistence.getStore<
Expand Down Expand Up @@ -472,7 +474,7 @@ export class IndexedDbPersistence implements Persistence {
}

if (!this.isLocalClient(currentPrimary)) {
if (!currentPrimary.allowTabSynchronization) {
if (!currentPrimary!.allowTabSynchronization) {
// Fail the `canActAsPrimary` check if the current leaseholder has
// not opted into multi-tab synchronization. If this happens at
// client startup, we reject the Promise returned by
Expand Down Expand Up @@ -710,7 +712,7 @@ export class IndexedDbPersistence implements Persistence {
!this.isClientZombied(currentPrimary.ownerId);

if (currentLeaseIsValid && !this.isLocalClient(currentPrimary)) {
if (!currentPrimary.allowTabSynchronization) {
if (!currentPrimary!.allowTabSynchronization) {
throw new FirestoreError(
Code.FAILED_PRECONDITION,
PRIMARY_LEASE_EXCLUSIVE_ERROR_MSG
Expand Down Expand Up @@ -798,7 +800,7 @@ export class IndexedDbPersistence implements Persistence {
) {
this.documentVisibilityHandler = () => {
this.queue.enqueueAndForget(() => {
this.inForeground = this.document.visibilityState === 'visible';
this.inForeground = this.document!.visibilityState === 'visible';
return this.updateClientMetadataAndTryBecomePrimary();
});
};
Expand All @@ -819,7 +821,7 @@ export class IndexedDbPersistence implements Persistence {
typeof this.document.addEventListener === 'function',
"Expected 'document.addEventListener' to be a function"
);
this.document.removeEventListener(
this.document!.removeEventListener(
'visibilitychange',
this.documentVisibilityHandler
);
Expand Down Expand Up @@ -877,7 +879,7 @@ export class IndexedDbPersistence implements Persistence {
process.env.USE_MOCK_PERSISTENCE === 'YES',
'Operating without LocalStorage is only supported with IndexedDbShim.'
);
return null;
return false;
}

try {
Expand All @@ -895,7 +897,7 @@ export class IndexedDbPersistence implements Persistence {
} catch (e) {
// Gracefully handle if LocalStorage isn't available / working.
log.error(LOG_TAG, 'Failed to get zombied client id.', e);
return null;
return false;
}
}

Expand Down
2 changes: 1 addition & 1 deletion packages/firestore/src/local/indexeddb_query_cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ export class IndexedDbQueryCache implements QueryCache {
.get(DbTargetGlobal.key)
.next(metadata => {
assert(metadata !== null, 'Missing metadata row.');
return metadata;
return metadata!;
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ export class IndexedDbRemoteDocumentCache implements RemoteDocumentCache {
changedKeys = changedKeys.unionWith(
this.serializer.fromDbResourcePaths(documentChange.changes)
);
this._lastProcessedDocumentChangeId = documentChange.id;
this._lastProcessedDocumentChangeId = documentChange.id!;
})
.next(() => {
const documentPromises: Array<PersistencePromise<void>> = [];
Expand Down
13 changes: 8 additions & 5 deletions packages/firestore/src/local/local_store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ export class LocalStore {
highestAck
);
} else {
return PersistencePromise.resolve([]);
return PersistencePromise.resolve([] as MutationBatch[]);
}
})
.next(ackedBatches =>
Expand Down Expand Up @@ -344,9 +344,12 @@ export class LocalStore {
.lookupMutationKeys(txn, batchId)
.next(keys => {
if (keys) {
return this.localDocuments.getDocuments(txn, keys);
return this.localDocuments.getDocuments(
txn,
keys
) as PersistencePromise<MaybeDocumentMap | null>;
} else {
return PersistencePromise.resolve(null);
return PersistencePromise.resolve<MaybeDocumentMap | null>(null);
}
});
}
Expand Down Expand Up @@ -883,7 +886,7 @@ export class LocalStore {
writesToRelease = this.queryCache
.getLastRemoteSnapshotVersion(txn)
.next(lastRemoteVersion => {
const toRelease = [];
const toRelease: MutationBatchResult[] = [];
for (const batchResult of this.heldBatchResults) {
if (batchResult.commitVersion.compareTo(lastRemoteVersion) > 0) {
break;
Expand Down Expand Up @@ -1036,7 +1039,7 @@ export class LocalStore {
return this.persistence.runTransaction('Get query data', false, txn => {
return this.queryCache
.getQueryDataForTarget(txn, targetId)
.next(queryData => queryData.query);
.next(queryData => (queryData ? queryData.query : null));
});
}
}
Expand Down
6 changes: 3 additions & 3 deletions packages/firestore/src/local/memory_mutation_queue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ export class MemoryMutationQueue implements MutationQueue {
const mutationBatch = this.findMutationBatch(batchId);
assert(mutationBatch != null, 'Failed to find local mutation batch.');
return PersistencePromise.resolve(
!mutationBatch.isTombstone() ? mutationBatch.keys() : null
!mutationBatch!.isTombstone() ? mutationBatch!.keys() : null
);
}

Expand All @@ -190,10 +190,10 @@ export class MemoryMutationQueue implements MutationQueue {
for (; index < size; index++) {
const batch = this.mutationQueue[index];
if (!batch.isTombstone()) {
return PersistencePromise.resolve(batch);
return PersistencePromise.resolve<MutationBatch | null>(batch);
}
}
return PersistencePromise.resolve(null);
return PersistencePromise.resolve<MutationBatch | null>(null);
}

getAllMutationBatches(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ export class RemoteDocumentChangeBuffer {

const bufferedEntry = changes.get(documentKey);
if (bufferedEntry) {
return PersistencePromise.resolve(bufferedEntry);
return PersistencePromise.resolve<MaybeDocument | null>(bufferedEntry);
} else {
return this.remoteDocumentCache.getEntry(transaction, documentKey);
}
Expand Down
Loading