-
Notifications
You must be signed in to change notification settings - Fork 787
increased strictness of types #695
Changes from 2 commits
fa0e148
e7be433
6708871
14a08fb
e652e08
e30b834
f7a5282
52811e8
658cb88
9ee0cc5
401f604
a36c853
9bc9367
e95593c
eb4e0c0
308316c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -29,7 +29,7 @@ import ApolloClient, { | |
} from 'apollo-client'; | ||
|
||
import { | ||
// GraphQLResult, | ||
ExecutionResult, | ||
DocumentNode, | ||
} from 'graphql'; | ||
|
||
|
@@ -50,11 +50,11 @@ export declare interface QueryOptions { | |
skip?: boolean; | ||
} | ||
|
||
export interface GraphQLDataProps { | ||
export interface QueryProps { | ||
error?: ApolloError; | ||
networkStatus: number; | ||
loading: boolean; | ||
variables: { | ||
variables?: { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i think this should not have the |
||
[variable: string]: any; | ||
}; | ||
fetchMore: (fetchMoreOptions: FetchMoreQueryOptions & FetchMoreOptions) => Promise<ApolloQueryResult<any>>; | ||
|
@@ -65,8 +65,33 @@ export interface GraphQLDataProps { | |
updateQuery: (mapFn: (previousQueryResult: any, options: UpdateQueryOptions) => any) => void; | ||
} | ||
|
||
export interface InjectedGraphQLProps<T> { | ||
data?: T & GraphQLDataProps; | ||
export type MutationFunc<TResult> = (opts: MutationOptions) => Promise<ApolloQueryResult<TResult>>; | ||
|
||
export interface OptionProps<TProps, TResult> { | ||
ownProps: TProps; | ||
data?: QueryProps & TResult; | ||
mutate?: MutationFunc<TResult>; | ||
} | ||
|
||
export type DefaultChildProps<P, R> = P & { data?: QueryProps & R, mutate?: MutationFunc<R> }; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wow this is dope There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. right? I'm wondering if I setup some overloads if we can get it to correctly type mutation / query / subscription. Going to try my hand at it tonight |
||
|
||
export interface OperationOption<TProps, TResult> { | ||
options?: QueryOptions | MutationOptions | ((props: TProps) => QueryOptions | MutationOptions); | ||
props?: (props: OptionProps<TProps, TResult>) => any; | ||
skip?: boolean | ((props: any) => boolean); | ||
name?: string; | ||
withRef?: boolean; | ||
shouldResubscribe?: (props: TProps, nextProps: TProps) => boolean; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would i.e. {
//...
shouldSubscribe: () => true //should be OK
} There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. that should still be fine, they should only be optional if the call can pass the variables as interface Test {
testFn (x: string, y: string): boolean;
}
let z: Test = {
// this is fine
testFn: () => true
}; |
||
alias?: string; | ||
} | ||
|
||
export type CompositeComponent<P> = ComponentClass<P> | StatelessComponent<P>; | ||
|
||
export interface ComponentDecorator<TOwnProps, TMergedProps> { | ||
(component: CompositeComponent<TMergedProps>): ComponentClass<TOwnProps>; | ||
} | ||
export interface InferableComponentDecorator<TOwnProps> { | ||
<T extends CompositeComponent<TOwnProps>>(component: T): T; | ||
} | ||
|
||
const defaultMapPropsToOptions = props => ({}); | ||
|
@@ -94,24 +119,10 @@ function getDisplayName(WrappedComponent) { | |
// Helps track hot reloading. | ||
let nextVersion = 0; | ||
|
||
export interface OperationOption { | ||
options?: Object | ((props: any) => QueryOptions | MutationOptions); | ||
props?: (props: any) => any; | ||
skip?: boolean | ((props: any) => boolean); | ||
name?: string; | ||
withRef?: boolean; | ||
shouldResubscribe?: (props: any, nextProps: any) => boolean; | ||
alias?: string; | ||
} | ||
|
||
export interface WrapWithApollo { | ||
<P, TComponentConstruct extends (ComponentClass<P> | StatelessComponent<P>)>(component: TComponentConstruct): TComponentConstruct; | ||
} | ||
|
||
export default function graphql( | ||
export default function graphql<TResult = {}, TProps = {}, TChildProps = DefaultChildProps<TProps, TResult>>( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i think you'll need to bump typescript to 2.3 in |
||
document: DocumentNode, | ||
operationOptions: OperationOption = {}, | ||
) { | ||
operationOptions: OperationOption<TProps, TResult> = {}, | ||
): ComponentDecorator<TProps, TChildProps> { | ||
|
||
// extract options | ||
const { options = defaultMapPropsToOptions, skip = defaultMapPropsToSkip, alias = 'Apollo' } = operationOptions; | ||
|
@@ -130,7 +141,7 @@ export default function graphql( | |
// Helps track hot reloading. | ||
const version = nextVersion++; | ||
|
||
const wrapWithApolloComponent: WrapWithApollo = WrappedComponent => { | ||
function wrapWithApolloComponent(WrappedComponent) { | ||
|
||
const graphQLDisplayName = `${alias}(${getDisplayName(WrappedComponent)})`; | ||
|
||
|
@@ -142,7 +153,7 @@ export default function graphql( | |
// However, this is an unlikely scenario. | ||
const recycler = new ObservableQueryRecycler(); | ||
|
||
class GraphQL extends Component<any, any> { | ||
class GraphQL extends Component<TProps, any> { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. not important, but can probably set state to |
||
static displayName = graphQLDisplayName; | ||
static WrappedComponent = WrappedComponent; | ||
static contextTypes = { | ||
|
@@ -297,11 +308,11 @@ export default function graphql( | |
return opts; | ||
} | ||
|
||
calculateResultProps(result) { | ||
calculateResultProps(result: (QueryProps & TResult) | MutationFunc<TResult>) { | ||
let name = this.type === DocumentType.Mutation ? 'mutate' : 'data'; | ||
if (operationOptions.name) name = operationOptions.name; | ||
|
||
const newResult = { [name]: result, ownProps: this.props }; | ||
const newResult: OptionProps<TProps, TResult> = { [name]: result, ownProps: this.props }; | ||
if (mapResultToProps) return mapResultToProps(newResult); | ||
|
||
return { [name]: defaultMapResultToProps(result) }; | ||
|
@@ -520,7 +531,7 @@ export default function graphql( | |
this.previousData = currentResult.data; | ||
} | ||
} | ||
return data; | ||
return (data as QueryProps & TResult); | ||
} | ||
|
||
render() { | ||
|
@@ -547,7 +558,7 @@ export default function graphql( | |
|
||
// Make sure we preserve any custom statics on the original component. | ||
return hoistNonReactStatics(GraphQL, WrappedComponent, {}); | ||
}; | ||
} | ||
|
||
return wrapWithApolloComponent; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this will be a breaking change for TS devs, right? Might be worth a mention in the changelog.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@stubailo for sure! I'll add that and note it in the release as well