为什么在TypeScript中赋值后,一个对象文字被认为与索引映射不兼容?
我在打字脚本代码中遇到了一些奇怪的情况:为什么在TypeScript中赋值后,一个对象文字被认为与索引映射不兼容?,typescript,Typescript,我在打字脚本代码中遇到了一些奇怪的情况: var a : { [name: string]: any } = { a: 'A' }; // WORKS! interface T { [name: string]: any }; var b : T = { a: 'A' }; // WORKS! interface Q<a> { [name: string]: a }; var c : Q<any> = { a: 'A' };
var a : { [name: string]: any } = { a: 'A' }; // WORKS!
interface T { [name: string]: any };
var b : T = { a: 'A' }; // WORKS!
interface Q<a> { [name: string]: a };
var c : Q<any> = { a: 'A' }; // WORKS!
var d = { a: 'A' };
c = d; // DOESN'T WORK
var a:{[name:string]:any}={a:'a'};//作品
接口T{[名称:字符串]:any};
变量b:T={a:'a'};//作品
接口Q{[名称:字符串]:a};
变量c:Q={a:'a'};//作品
var d={a:'a'};
c=d;//不起作用
谁能给我解释一下有什么问题吗
Error 1 Cannot convert '{ a: string; }' to 'Q<any>':
Index signatures of types '{ a: string; }' and 'Q<any>' are incompatible.
错误1无法将“{a:string;}”转换为“Q”:
类型“{a:string;}”和“Q”的索引签名不兼容。
如果您考虑:
var d = { a: 'A' };
d
的类型可推断为:
var d: { a : string };
要使TypeScript声明两种类型相同,当它们是索引签名时,它们必须是具有相同类型的相同类型。(来自规范中的3.8.2)
因此,这不起作用:
c = d;
因为它实际上被视为以下两种类型定义:
{ [name: string] : any } = { a : string };
它们不完全相同(因为它们不是完全相同的索引签名)
当您直接在强类型变量(如c
)上创建和设置值时,该类型是众所周知的
如果添加了其他测试:
var e: { a: string } = { a: 'A'};
e = d;
您将看到e
如何在没有警告的情况下接受d
的值。
c=e
其他集合正在工作,因为您已经显式地声明了类型,因此正确地推断了类型(并且正如您所看到的那样工作)。这种行为类似于另一种语言,其中的类型类似于
int
,例如:intmyvar=6代码>。在这种情况下,6
将被视为一个int
,即使它可以被表示为一个字节
。TypeScript中的某个地方不是有鸭子打字的东西吗?据我记忆所及,只要源对象的表面和目标对象兼容,就应该允许分配它。如果是这样的话,Q与任何普通对象都是兼容的,因为它只是一个普通对象在索引方面的定义。正如我提到的,它们都不共享索引签名。文档中非常明确,我不希望duck类型覆盖这种行为。感谢@basarat,正如您所指出的,我将声明更新为一个字符串。