我在这里有一些示例代码:
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,
}));
如预期的那样,这里我将出现错误Property 'buz' is missing in type '{ bar: string; }'
。
但是如果我将fooList
的类型更改为any
,TS就会认为一切都很好:
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,
}));
在第二种情况下,我期望与第一种情况下的错误相同。为什么TS在第二种情况下不会引发错误?
答案 0 :(得分:2)
因为any
很特殊。 documentation说,这是一种方法
选择退出类型检查,并让值通过编译时检查。
因此,如果您将某物声明为any
,则可以为其分配任何内容,为其分配任何内容,访问其任何属性,调用其任何方法,并且编译器将不会抱怨,并推断出{{ 1}}键入任何此类操作的结果。
如果在第二个示例中省略了any
的类型注释,您将看到它的类型被推断为newList
,因此可以将其分配给any
。
答案 1 :(得分:2)
由于fooList
的类型为any
,编译器也无法推断有关函数fooList.map
的任何内容(请记住,它甚至不再知道fooList
是数组)。
因此,它不知道map
返回什么,也不知道您传递给map
的委托有什么作用。它不知道您的委托结果将从map
作为数组中的元素返回,这意味着它不知道您的委托结果应为{{1}类型},因此不知道会警告您它不是有效的Foo
。
如果您将Foo
设置为键入fooList
而不是any[]
,则编译器将知道它是一个数组,并将知道函数any
的行为,并会给您预期的错误。
或者,您可以明确地告诉它,您的委托人应该返回fooList.map
:
Foo
在将const newList: Foo[] = fooList.map((foo: Foo): Foo => ({
bar: foo.bar,
}));
保留为fooList
类型的同时,还将允许它给您预期的错误。