lequan
lequan

Reputation: 48

Type is not checking for any type

I have some example code here:

interface Foo {
    bar: string;
    buz: string;
}
const fooList: Foo[] = [
    { bar: '1', buz: '1' },
    { bar: '2', buz: '2' }
];
const newList: Foo[] = fooList.map((foo: Foo) => ({
    bar: foo.bar,
}));

As expected, here I will have an error Property 'buz' is missing in type '{ bar: string; }'.

But if I change type of fooList to any TS start to thinks that everything is fine:

interface Foo {
    bar: string;
    buz: string;
}
const fooList: any = [
    { bar: '1', buz: '1' },
    { bar: '2', buz: '2' }
];
const newList: Foo[] = fooList.map((foo: Foo) => ({
    bar: foo.bar,
}));

In second case, I expected same error as in the first case. Why TS doesn't throw an error in the second case?

Upvotes: 0

Views: 44

Answers (2)

James Thurley
James Thurley

Reputation: 2900

Because fooList is of type any the compiler also cannot infer anything about the function fooList.map (remember it no longer even knows fooList is an array).

Therefore it does not know what map returns, nor what it does with the delegate you passed in to map. It doesn't know that the result of your delegate will be returned from map as an element in an array, which means it doesn't know that the result of your delegate is meant to be of type Foo, and therefore it doesn't know to warn you that it isn't a valid Foo.

If you set fooList to type any[] instead of any then the compiler will know that it is an array, will know about the behaviour of the function fooList.map, and will give you the expected error.

Alternatively you could explicitly tell it that your delegate should return a Foo:

const newList: Foo[] = fooList.map((foo: Foo): Foo => ({
    bar: foo.bar,
}));

Which will also allow it to give you the expected error while keeping fooList as type any.

Upvotes: 2

artem
artem

Reputation: 51649

Because any is special. The documentation says that it's a way to

opt-out of type-checking and let the values pass through compile-time checks.

So if you declare something as any, you can assign anything to it, assign it to anything, access any property of it, call any method of it and the compiler will not complain, and infer the any type for the result of any such operation.

If you omit type annotation for newList in the second example, you will see that it's type is inferred as any, so it's assignable to Foo[].

Upvotes: 2

Related Questions