0

Description

I have two interfaces (MiddlewareResponse & MiddlewareResponseNext) which should be the only two possible return type for both a function or an asynchronous function (CallbackOrPromiseCallback).

But in the example below, TypeScript does not complain when using a wrong return type for the function.

Question

What should I do in TypeScript to make sure that the union type as a return type of a function or an asynchronous function is correctly typed, and prevent possible typing mistakes?

Source-code

type CallbackOrPromiseCallback<Type> = (() => Promise<Type>) | (() => Type);

interface MiddlewareResponseNext {
    next: true;
}

interface MiddlewareResponse {
    next: false,
    headers: Record<string, string>;
    status: number;
    body: string;
}

interface Middleware {
    response: CallbackOrPromiseCallback<MiddlewareResponse | MiddlewareResponseNext>;
}

interface Server {
    middlewares: Array<Middleware>;
}

const server = {
    middlewares: [
        {
            response: () => ({
                next: true,
                status: 200 // Should not accept anymore properties
            })
        },
        {
            response: () => ({
                next: true, // Should be forced to false
                headers: {},
                status: 500,
                body: "Error"
            })
        }
    ]
};

Playground

TypeScript Playground.

Amin NAIRI
  • 2,292
  • 21
  • 20
  • I'm not sure how to get exhaustive property checks here. It's not really an "error" to have excess properties. Both of your return types are assignable to `MiddlewareResponseNext`. If you add something that makes them incompatible, like `interface MiddlewareResponseNext { next: true; headers: string; }` *then* you get the error on the second one `Type 'true' is not assignable to type 'false'` – Linda Paiste Mar 19 '21 at 22:22
  • I see, I was expecting it to raise an error since using one or the other interface in a standalone way like `const middleware: MiddlewareResponseNext = {next: true, status: 200}` would raise an error. I guess TypeScript has been designed that way but I was expecting it to check whether the users are mistyping their middleware response. This also means that I will have to check that at runtime. Not sure if there is another way of handling this case in TypeScript. – Amin NAIRI Mar 20 '21 at 09:35
  • 1
    You can search for answers regarding excess properties. Here’s one: https://stackoverflow.com/a/54775885/10431574 – Linda Paiste Mar 20 '21 at 17:41

0 Answers0