I'm starting my journey with ts
and looking into TypeGraphQL right now.
I've noticed something I don't understand and haven't seen before:
export declare type ReturnTypeFunc = (returns?: void) => ReturnTypeFuncValue;
How should that type be interpreted? What does this (returns?: void)
represent?
CodePudding user response:
The function signature you described is here, and its usage of the optional parameter of type void
could be written for a number of reasons.
One reason is as a means of preventing callers from providing an argument in normal circumstances, but to allow for internal library code to make use of undocumented, internal logic that might depend on functional use of the value.
Here's a very contrived example that demonstrates what I described above:
function fn (param?: void): void {
if ((param as any) === 'log a special message') {
console.log('Internal behavior matched');
}
};
fn(); // Ok
fn('hello'); // Not ok
/**
* Written as returning void, but actually returns
* something that is used for internal library behavior
*/
function internalFnForInteralThings (): void {
return 'log a special message' as any;
};
fn(internalFnForInteralThings()); // Ok (and logs "Internal behavior matched")
Ultimately, you'd have to examine the whole codebase of the project that exports the type to see how it is used in each case, and then using that knowledge, you could infer why the author chose to write the signature that way.
CodePudding user response:
The type ReturnTypeFunc
is used in the Query
decorator:
export declare function Query(returnTypeFunc: ReturnTypeFunc, options?: AdvancedOptions): MethodDecorator;
This is how Query
decorator is usually used:
@Query(returns => [SampleObject])
As far as I remember, the parameter returns
is added to help with the readability: This query returns an array of SampleObject
. If you remove the returns
argument in type ReturnTypeFunc
, you cannot do this anymore, and you have to write @Query(() => [SampleObject])
instead.
Some other decorators that have an optional void argument are:
@Resolver(of => Recipe) // This is a resolver for Recipe. See type ClassTypeResolver
@Field(type => [Rate]) // This field is of type Rate. See type ClassTypeResolver.
Edit:
- As mentioned in the comments, you can only assign
null
(ifstrictNullChecks
is not specified) orundefined
to a variable of typevoid
. - The mentioned decorators annotate classes. The graphql schema is generated by using the provided metadata to the decorators. To the best of my knowledge, you are not supposed to define a function that is of type
ReturnTypeFunc
. The only reason those parameters are of typevoid
, is to improve readability of code.