我试图弄清楚隐式索引签名的规则是什么,但在此示例中被卡住了:
比方说,我们希望某些返回类型遵循带有索引签名的接口:
interface A { [index: string]: string }
const getA = (): A => {
return { a : 'a' }
}
这当然是有效的,因为{ a : 'a' }
是隐式的any
,而any
可以隐式地转换为其他所有内容。
让我们说我们对返回的内容有些挑剔,也许是类型为B
的某些结果,我们想要隐式映射到接口A:
interface A { [index: string]: string }
interface B { b: string }
const getA = () : A => {
return { b : 'b' } as B
}
这不起作用,因为接口B被明确定义为没有索引签名。我的想法在这里正确吗? (注意:我真的很想这样做,但是也许不可能)
产生的错误:
类型'B'不能分配给类型'A'。缺少索引签名 输入“ B”。
但是,这就是让我感到困惑的地方,对interface A
的定义稍松一些可以让我们再次编译:
interface A { [index: string]: any }
interface B { b: string }
const getA = () : A => {
return { b : 'b' } as B
}
为什么?难道B
上仍然缺少索引签名吗?
答案 0 :(得分:2)
这当然有效,因为{a:'a'}隐含了任何
这是错误的。 { a : 'a' }
的类型为{ a: 'a' }
。
此函数没有错误,因为TypeScript可以看到您正在返回新的对象文字(也称为“新鲜”)。如果它是一个新的对象文字,则它不能具有任何其他属性,因此TypeScript可以静态检查其所有属性是否可分配给索引签名类型。
在下一个示例中,类型断言{ b : 'b' } as B
使新鲜度检查失败(类型断言总是删除有关原始表达式的所有类型信息)。由于TypeScript不能判断此表达式是否实际上是该表达式的别名,该表达式可能具有其他属性,因此必须发出错误。
在上一个示例中,您说过([index: string]: any]
),需要一个对象,其所有属性在某种程度上都与any
兼容。您编写的对象是否是其属性都与any
兼容的对象?当然是的;所有类型都具有该属性。这样代码就可以了。