Home > Blockchain >  Typescript "Object literal may only specify known properties" not effects on Promise retur
Typescript "Object literal may only specify known properties" not effects on Promise retur

Time:10-13

Typescript will check unknown properties:

(below will have error: "'c' does not exist in type...")

interface IReturnVal {
    a: boolean;
    b: boolean;
}

function oh(): IReturnVal {
    return {
        a: true,
        b: false,
        c: 1, // Type '{ a: true; b: false; c: number; }' is not assignable to type 'IReturnVal'. Object literal may only specify known properties, and 'c' does not exist in type 'IReturnVal'.ts(2322)
    };
}

oh();

However if functions returning Promise, Typescript will only check for missing properties

(below will have error: "Property 'a' is missing in type...")

interface IReturnVal {
    a: boolean;
    b: boolean;
}

function ok(): Promise<IReturnVal> {
    //  Property 'a' is missing in type ....
    return Promise.resolve({
        b: false,
    });
}
ok();

But not checking unknown properties.

(below will not have any error or warning)

expect: Have error"Object literal may only specify known properties..."

interface IReturnVal {
    a: boolean;
    b: boolean;
}

function ok(): Promise<IReturnVal> {
    return Promise.resolve({
        a: true,
        b: false,
        c: 1, // will not cause any error or warning
    });
}
ok();

Is this the expect behavior or I'm missing something in Typescript setting?

CodePudding user response:

The reason it's not raising an error in your example is that your code isn't immediately returning an object literal, it's returning the result of calling a function. Excess property checks only apply to object literals. Since the function (Promise.resolve) is returning Promise<{a: boolean, b: boolean, c: number}> and that's assignment-compatible with ok's Promise<{a: boolean, b: boolean}> return type, TypeScript doesn't complain.

You can make TypeScript check the object literal you're passing into Promise.resolve by providing a type argument to Promise.resolve:

interface IReturnVal {
    a: boolean;
    b: boolean;
}

function ok(): Promise<IReturnVal> {
    return Promise.resolve<IReturnVal>({
    //                    ^^^^^^^^^^^^
        a: true,
        b: false,
        c: 1, // <== error here as desired
    });
}
ok();

Playground link

Alternatively, you can make ok an async function:

    interface IReturnVal {
        a: boolean;
        b: boolean;
    }
    async function ok(): Promise<IReturnVal> {
//  ^^^^^
        return {
            a: true,
            b: false,
            c: 1, // <== error here as desired
        };
    }
    ok();

Playground link

For the avoidance of doubt: async functions always return promises. If you return a non-promise, it gets wrapped in a promise as though passed through Promise.resolve.

  • Related