Skip to content

Commit

Permalink
enable TypeScript strictNullChecks
Browse files Browse the repository at this point in the history
  • Loading branch information
calebmer committed Jan 23, 2017
1 parent 7488053 commit 54f7b98
Show file tree
Hide file tree
Showing 31 changed files with 108 additions and 107 deletions.
5 changes: 4 additions & 1 deletion src/core/ObservableQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,10 @@ export class ObservableQuery<T> extends Observable<ApolloQueryResult<T>> {
const { data, partial } = this.queryManager.getCurrentQueryResult(this, true);
const queryStoreValue = this.queryManager.getApolloState().queries[this.queryId];

if (queryStoreValue && (queryStoreValue.graphQLErrors || queryStoreValue.networkError)) {
if (queryStoreValue && (
(queryStoreValue.graphQLErrors && queryStoreValue.graphQLErrors.length > 0) ||
queryStoreValue.networkError
)) {
const error = new ApolloError({
graphQLErrors: queryStoreValue.graphQLErrors,
networkError: queryStoreValue.networkError,
Expand Down
5 changes: 4 additions & 1 deletion src/core/QueryManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,10 @@ export class QueryManager {

// If we have either a GraphQL error or a network error, we create
// an error and tell the observer about it.
if (queryStoreValue.graphQLErrors || queryStoreValue.networkError) {
if (
(queryStoreValue.graphQLErrors && queryStoreValue.graphQLErrors.length > 0) ||
queryStoreValue.networkError
) {
const apolloError = new ApolloError({
graphQLErrors: queryStoreValue.graphQLErrors,
networkError: queryStoreValue.networkError,
Expand Down
2 changes: 1 addition & 1 deletion src/core/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,4 @@ export enum FetchType {
poll = 3,
}

export type IdGetter = (value: Object) => string;
export type IdGetter = (value: Object) => string | null | undefined;
2 changes: 1 addition & 1 deletion src/data/storeUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ export interface JsonValue {
json: any;
}

export type StoreValue = number | string | string[] | IdValue | JsonValue | void;
export type StoreValue = number | string | string[] | IdValue | JsonValue | null | undefined | void;

export function isIdValue(idObject: StoreValue): idObject is IdValue {
return (
Expand Down
8 changes: 4 additions & 4 deletions src/data/writeToStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export function writeQueryToStore({
query,
store = {} as NormalizedCache,
variables,
dataIdFromObject = null,
dataIdFromObject,
fragmentMap = {} as FragmentMap,
}: {
result: Object,
Expand Down Expand Up @@ -99,7 +99,7 @@ export function writeResultToStore({
document,
store = {} as NormalizedCache,
variables,
dataIdFromObject = null,
dataIdFromObject,
}: {
dataId: string,
result: any,
Expand Down Expand Up @@ -172,7 +172,7 @@ export function writeSelectionSetToStore({
fragment = selection;
} else {
// Named fragment
fragment = fragmentMap[selection.name.value];
fragment = (fragmentMap || {})[selection.name.value];

if (!fragment) {
throw new Error(`No fragment named ${selection.name.value}.`);
Expand Down Expand Up @@ -236,7 +236,7 @@ function writeFieldToStore({
// specifies if we need to merge existing keys in the store
let shouldMerge = false;
// If we merge, this will be the generatedKey
let generatedKey: string;
let generatedKey: string = '';

// If this is a scalar value...
if (!field.selectionSet || value === null) {
Expand Down
8 changes: 4 additions & 4 deletions src/errors/ApolloError.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import { GraphQLError } from 'graphql';
export class ApolloError extends Error {
public message: string;
public graphQLErrors: GraphQLError[];
public networkError: Error;
public networkError: Error | null;

// An object that can be used to provide some additional information
// about an error, e.g. specifying the type of error this is. Used
Expand All @@ -50,13 +50,13 @@ export class ApolloError extends Error {
extraInfo,
}: {
graphQLErrors?: GraphQLError[],
networkError?: Error,
networkError?: Error | null,
errorMessage?: string,
extraInfo?: any,
}) {
super(errorMessage);
this.graphQLErrors = graphQLErrors;
this.networkError = networkError;
this.graphQLErrors = graphQLErrors || [];
this.networkError = networkError || null;

// set up the stack trace
this.stack = new Error().stack;
Expand Down
2 changes: 1 addition & 1 deletion src/mutations/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export interface MutationStoreValue {
mutationString: string;
variables: Object;
loading: boolean;
error: Error;
error: Error | null;
}

export interface SelectionSetWithRoot {
Expand Down
12 changes: 4 additions & 8 deletions src/queries/directives.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,7 @@ import {
} from 'graphql';


export function shouldInclude(selection: SelectionNode, variables?: { [name: string]: any }): boolean {
if (!variables) {
variables = {};
}

export function shouldInclude(selection: SelectionNode, variables: { [name: string]: any } = {}): boolean {
if (!selection.directives) {
return true;
}
Expand All @@ -25,19 +21,19 @@ export function shouldInclude(selection: SelectionNode, variables?: { [name: str
}

//evaluate the "if" argument and skip (i.e. return undefined) if it evaluates to true.
const directiveArguments = directive.arguments;
const directiveArguments = directive.arguments || [];
const directiveName = directive.name.value;
if (directiveArguments.length !== 1) {
throw new Error(`Incorrect number of arguments for the @${directiveName} directive.`);
}


const ifArgument = directive.arguments[0];
const ifArgument = directiveArguments[0];
if (!ifArgument.name || ifArgument.name.value !== 'if') {
throw new Error(`Invalid argument for the @${directiveName} directive.`);
}

const ifValue = directive.arguments[0].value;
const ifValue = directiveArguments[0].value;
let evaledValue: boolean = false;
if (!ifValue || ifValue.kind !== 'BooleanValue') {
// means it has to be a variable value if this is a valid @skip or @include directive
Expand Down
11 changes: 5 additions & 6 deletions src/queries/getFromAST.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
export function getMutationDefinition(doc: DocumentNode): OperationDefinitionNode {
checkDocument(doc);

let mutationDef: OperationDefinitionNode = null;
let mutationDef: OperationDefinitionNode | null = null;
doc.definitions.forEach((definition) => {
if (definition.kind === 'OperationDefinition'
&& (definition as OperationDefinitionNode).operation === 'mutation') {
Expand Down Expand Up @@ -55,9 +55,8 @@ string in a "gql" tag? http://docs.apollostack.com/apollo-client/core.html#gql`)
export function getOperationName(doc: DocumentNode): string {
let res: string = '';
doc.definitions.forEach((definition) => {
if (definition.kind === 'OperationDefinition'
&& (definition as OperationDefinitionNode).name) {
res = (definition as OperationDefinitionNode).name.value;
if (definition.kind === 'OperationDefinition' && definition.name) {
res = definition.name.value;
}
});
return res;
Expand All @@ -79,7 +78,7 @@ export function getFragmentDefinitions(doc: DocumentNode): FragmentDefinitionNod
export function getQueryDefinition(doc: DocumentNode): OperationDefinitionNode {
checkDocument(doc);

let queryDef: OperationDefinitionNode = null;
let queryDef: OperationDefinitionNode | null = null;
doc.definitions.map((definition) => {
if (definition.kind === 'OperationDefinition'
&& (definition as OperationDefinitionNode).operation === 'query') {
Expand All @@ -98,7 +97,7 @@ export function getQueryDefinition(doc: DocumentNode): OperationDefinitionNode {
export function getOperationDefinition(doc: DocumentNode): OperationDefinitionNode {
checkDocument(doc);

let opDef: OperationDefinitionNode = null;
let opDef: OperationDefinitionNode | null = null;
doc.definitions.map((definition) => {
if (definition.kind === 'OperationDefinition') {
opDef = definition as OperationDefinitionNode;
Expand Down
7 changes: 4 additions & 3 deletions src/queries/queryTransform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import { cloneDeep } from '../util/cloneDeep';

const TYPENAME_FIELD: FieldNode = {
kind: 'Field',
alias: null,
name: {
kind: 'Name',
value: '__typename',
Expand All @@ -26,7 +25,7 @@ function addTypenameToSelectionSet(
selectionSet: SelectionSetNode,
isRoot = false,
) {
if (selectionSet && selectionSet.selections) {
if (selectionSet.selections) {
if (! isRoot) {
const alreadyHasThisField = selectionSet.selections.some((selection) => {
return selection.kind === 'Field' && (selection as FieldNode).name.value === '__typename';
Expand All @@ -39,7 +38,9 @@ function addTypenameToSelectionSet(

selectionSet.selections.forEach((selection) => {
if (selection.kind === 'Field' || selection.kind === 'InlineFragment') {
addTypenameToSelectionSet((selection as FieldNode | InlineFragmentNode).selectionSet);
if (selection.selectionSet) {
addTypenameToSelectionSet(selection.selectionSet);
}
}
});
}
Expand Down
10 changes: 5 additions & 5 deletions src/queries/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ export type QueryStoreValue = {
queryString: string;
document: DocumentNode;
variables: Object;
previousVariables: Object;
previousVariables: Object | null;
networkStatus: NetworkStatus;
networkError: Error;
networkError: Error | null;
graphQLErrors: GraphQLError[];
forceFetch: boolean;
returnPartialData: boolean;
Expand Down Expand Up @@ -65,7 +65,7 @@ export function queries(

let isSetVariables = false;

let previousVariables: Object;
let previousVariables: Object | null = null;
if (
action.storePreviousVariables &&
previousQuery &&
Expand Down Expand Up @@ -101,7 +101,7 @@ export function queries(
variables: action.variables,
previousVariables,
networkError: null,
graphQLErrors: null,
graphQLErrors: [],
networkStatus: newNetworkStatus,
forceFetch: action.forceFetch,
returnPartialData: action.returnPartialData,
Expand Down Expand Up @@ -166,7 +166,7 @@ export function queries(
// and do not need to hit the server. Not sure when we'd fire this action if the result is not complete, so that bears explanation.
// We should write that down somewhere.
networkStatus: action.complete ? NetworkStatus.ready : NetworkStatus.loading,
} as QueryStoreValue;
};

return newState;
} else if (isQueryStopAction(action)) {
Expand Down
6 changes: 5 additions & 1 deletion src/scheduler/scheduler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ export class QueryScheduler {

public startPollingQuery<T>(
options: WatchQueryOptions,
queryId?: string,
queryId: string,
listener?: QueryListener,
): string {
if (!options.pollInterval) {
Expand Down Expand Up @@ -135,6 +135,10 @@ export class QueryScheduler {
public addQueryOnInterval<T>(queryId: string, queryOptions: WatchQueryOptions) {
const interval = queryOptions.pollInterval;

if (!interval) {
throw new Error(`A poll interval is required to start polling query with id '${queryId}'.`);
}

// If there are other queries on this interval, this query will just fire with those
// and we don't need to create a new timer.
if (this.intervalQueries.hasOwnProperty(interval.toString()) && this.intervalQueries[interval].length > 0) {
Expand Down
2 changes: 1 addition & 1 deletion src/transport/batchedNetworkInterface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,5 +141,5 @@ export function createBatchingNetworkInterface(options: BatchingNetworkInterface
if (! options) {
throw new Error('You must pass an options argument to createNetworkInterface.');
}
return new HTTPBatchedNetworkInterface(options.uri, options.batchInterval, options.opts);
return new HTTPBatchedNetworkInterface(options.uri, options.batchInterval, options.opts || {});
}
4 changes: 2 additions & 2 deletions src/transport/batching.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export class QueryBatcher {

// Consumes the queue. Called on a polling interval.
// Returns a list of promises (one for each query).
public consumeQueue(): Promise<ExecutionResult>[] | undefined {
public consumeQueue(): (Promise<ExecutionResult> | undefined)[] | undefined {
if (this.queuedRequests.length < 1) {
return undefined;
}
Expand All @@ -67,7 +67,7 @@ export class QueryBatcher {
};
});

const promises: Promise<ExecutionResult>[] = [];
const promises: (Promise<ExecutionResult> | undefined)[] = [];
const resolvers: any[] = [];
const rejecters: any[] = [];
this.queuedRequests.forEach((fetchRequest, index) => {
Expand Down
16 changes: 9 additions & 7 deletions src/transport/networkInterface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ export class HTTPFetchNetworkInterface implements NetworkInterface {
public _middlewares: MiddlewareInterface[];
public _afterwares: AfterwareInterface[];

constructor(uri: string, opts: RequestInit = {}) {
constructor(uri: string | undefined, opts: RequestInit = {}) {
if (!uri) {
throw new Error('A remote endpoint is required for a network layer');
}
Expand All @@ -112,7 +112,9 @@ export class HTTPFetchNetworkInterface implements NetworkInterface {
const next = () => {
if (funcs.length > 0) {
const f = funcs.shift();
f.applyMiddleware.apply(scope, [{ request, options }, next]);
if (f) {
f.applyMiddleware.apply(scope, [{ request, options }, next]);
}
} else {
resolve({
request,
Expand Down Expand Up @@ -229,19 +231,19 @@ export function createNetworkInterface(
throw new Error('You must pass an options argument to createNetworkInterface.');
}

let uri: string;
let opts: RequestInit;
let uri: string | undefined;
let opts: RequestInit | undefined;

// We want to change the API in the future so that you just pass all of the options as one
// argument, so even though the internals work with two arguments we're warning here.
if (typeof uriOrInterfaceOpts === 'string') {
console.warn(`Passing the URI as the first argument to createNetworkInterface is deprecated \
as of Apollo Client 0.5. Please pass it as the "uri" property of the network interface options.`);
opts = secondArgOpts;
uri = uriOrInterfaceOpts as string;
uri = uriOrInterfaceOpts;
} else {
opts = (uriOrInterfaceOpts as NetworkInterfaceOptions).opts;
uri = (uriOrInterfaceOpts as NetworkInterfaceOptions).uri;
opts = uriOrInterfaceOpts.opts;
uri = uriOrInterfaceOpts.uri;
}
return new HTTPFetchNetworkInterface(uri, opts);
}
10 changes: 5 additions & 5 deletions test/ObservableQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -256,8 +256,8 @@ describe('ObservableQuery', () => {
});

it('does a network request if noFetch becomes true then store is reset then noFetch becomes false', (done) => {
let queryManager: QueryManager = null;
let observable: ObservableQuery<any> = null;
let queryManager: QueryManager;
let observable: ObservableQuery<any>;
const testQuery = gql`
query {
author {
Expand Down Expand Up @@ -309,8 +309,8 @@ describe('ObservableQuery', () => {
});

it('does a network request if noFetch becomes false', (done) => {
let queryManager: QueryManager = null;
let observable: ObservableQuery<any> = null;
let queryManager: QueryManager;
let observable: ObservableQuery<any>;
const testQuery = gql`
query {
author {
Expand Down Expand Up @@ -637,7 +637,7 @@ describe('ObservableQuery', () => {
const currentResult = observable.currentResult();

assert.equal(currentResult.loading, false);
assert.deepEqual(currentResult.error.graphQLErrors, [error]);
assert.deepEqual(currentResult.error!.graphQLErrors, [error]);
});
});

Expand Down
Loading

0 comments on commit 54f7b98

Please sign in to comment.