Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么在TypeScript中赋值后,一个对象文字被认为与索引映射不兼容?_Typescript - Fatal编程技术网

为什么在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,正如您所指出的,我将声明更新为一个
字符串。