Can Generics be marked as mandatory in typescript?
function validateGenerics<Result, Variables>({
foo,
bar
}: {
foo: Result
bar: Variables
}) {
console.log(foo, bar)
}
// Attempting to call the function without passing Generics should not work
validateGenerics({ foo: 'foo', bar: 'bar' })
// Calling the function with specified Generics should work as expected
validateGenerics<number, number>({ foo: 'foo', bar: 'bar' })
Edit
I have found a solution to my question and it works perfectly. I can illustrate why this feature is important through an example.
validateGenerics<UpdateUserMutation, UpdateUserMutationVariables>({
mutation: UpdateUserDocument,
variables: { id: user.id, user: formData },
refetchQueries: ['GetUserList'],
onSuccess: ({ data }) => history.push(`/users/${data.updateUser.id}`),
})
If I omit
<UpdateUserMutation, UpdateUserMutationVariables>
, I will not know what data
represents in the onSuccess
function. Additionally, I may forget to include specific variables in the variables
object and the IDE integration might suffer :-)
Although I could manually type { data }
, using Generics ensures that I never miss specifying the necessary variables for the function calls.
For those curious about my updated validateGenerics
function:
function validateGenerics<
Result = [Error, 'Please specify the Result type parameter'],
Variables = [Error, 'Please specify the Variables type parameter'],
R extends Result = Result,
V extends Variables = Variables
>({
mutation,
variables,
refetchQueries,
onSuccess,
}: {
mutation: DocumentNode
variables: V
refetchQueries: ((string | PureQueryOptions)[]) | (string | PureQueryOptions)[]
onSuccess: (response: FetchResult<R, Record<string, any>, Record<string, any>>) => void
}) {
client
.mutate<R>({
mutation,
variables,
refetchQueries,
})
.then(response => {
setErrors({})
onSuccess(response)
})
.catch(handleErrors)
}