user2010955
user2010955

Reputation: 4011

typescript array.map lost returned type

I would expect a type error in the following code, but for typescript is perfectly ok, can you tell me why?

export interface Structure {
    aaa: string;
}

export function f1(): Structure[] {  // OK for typescript, not for me
    const result = [].map(certState => {
        return {
            aaa: 'aaa',
            ADDITIONAL_FIELD: 'asdf'
        }
    });

    return result;
}

export function f2(): Structure[] { // ERROR for typescript (and for me)
        return [
            {
                aaa: 'sdf',
                ADDITIONAL_FIELD: 'asdf'
            }
        ]
    }

Here is the link

Thanks!

Upvotes: 2

Views: 1164

Answers (2)

user2010955
user2010955

Reputation: 4011

I just learn that Typescript has a concept of exact types only for object literals, so f1 is not using object literals, so additional properties cannot be add and it's valid for typescript. f2 uses object literals, so additional properties are not allowed. This scare me a lot, but that's how typescript works

Upvotes: 0

frix
frix

Reputation: 165

The error is due to the fact that in f2() you are directly returning your result.

If you changed f2() to be

export function f2(): Structure[] {
    const returnVal = [
        {
            aaa: 'sdf',
            ADDITIONAL_FIELD: 'asdf'
        }
    ]

    return returnVal;
}

then there would be no compiler error.

TypeScript uses structural typing to determine type compatibility, so in your code for f1(), result is of type

{
   aaa: string,
   ADDITIONAL_FIELD: string
}[]

which is compatible with Structure[] (there is no danger in type narrowing).

I'm not 100% sure why directly returning doesn't work, but my assumption is that in f2() you are telling the compiler that "this specific array is of type Structure[]" and it says no it's not. When you have an intermediate variable in f1() you are saying "this function returns Structure[]" and when you return the intermediate variable the compiler checks and says "okay result matches Structure[]" so this function is doing what it says.

I'd be curious to hear if others have a more rigorous explanation

Upvotes: 2

Related Questions