简体   繁体   中英

typescript: void parameter type in function type declaration

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?

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:

  1. As mentioned in the comments, you can only assign null (if strictNullChecks is not specified) or undefined to a variable of type void .
  2. 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 type void , is to improve readability of code.

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:

TS Playground

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM