TypeScript: void-parameter typ i funktionsdeklaration


Jag börjar min resa med ts och kollar på TypeGraphQL just nu. Jag har märkt något jag inte förstår och inte sett tidigare:

export declare type ReturnTypeFunc = (returns?: void) => ReturnTypeFuncValue;

Hur ska den typen tolkas? Vad representerar detta (returns?: void)?

Svar #1

Typen ReturnTypeFunc används i Query-dekoratören:

export declare function Query(returnTypeFunc: ReturnTypeFunc, options?: AdvancedOptions): MethodDecorator;

Så här används Query-dekorationen vanligtvis:

  @Query(returns => [SampleObject])

Såvitt jag minns är parametern returns tillagd för att hjälpa med läsbarheten: Denna fråga returnerar en array av SampleObject. Om du tar bort returns-argumentet i typen ReturnTypeFunc kan du inte göra detta längre, och du måste skriva @Query(() => [SampleObject]) istället.

Några andra dekoratörer som har ett valfritt void-argument är:

@Resolver(of => Recipe) // This is a resolver for Recipe. See type ClassTypeResolver

@Field(type => [Rate]) // This field is of type Rate. See type ClassTypeResolver.

Redigera:

  1. Som nämnts i kommentarerna kan du endast tilldela null (om strictNullChecks inte är specificerat) eller undefined till en variabel av typen void.
  2. De nämnda dekoratörerna annoterar klasser. GraphQL-schemat genereras genom att använda den metadata som tillhandahålls till dekoratörerna. Så vitt jag vet är det inte meningen att du ska definiera en funktion som är av typen ReturnTypeFunc. Den enda anledningen till att dessa parametrar är av typen void är att förbättra kodens läsbarhet.

Svar #2

Funktionssignaturen du beskrev är här, och dess användning av den valfria parametern av typen void kan skrivas av flera skäl.

En anledning är som ett sätt att förhindra att samtalare anger ett argument under normala omständigheter, men för att tillåta intern biblioteks-kod att använda odokumenterad, intern logik som kan bero på funktionell användning av värdet.

Här är ett mycket påtvingat exempel som visar vad jag beskrev ovan:

TS Lekplats

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")

I slutändan skulle du behöva granska hela kodbasen för projektet som exporterar typen för att se hur den används i varje fall, och sedan, med den kunskapen, skulle du kunna dra slutsatsen varför författaren valde att skriva signaturen på det sättet.