[英]Why can't I indirectly return an object literal to satisfy an index signature return type in TypeScript?
这三个函数似乎做同样的事情,但最后一个是错误。 为什么会这样?
interface StringMap {
[key: string]: string;
}
function a(): StringMap {
return { a: "1" }; // OK
}
function b(): StringMap {
var result: StringMap = { a: "1" };
return result; // OK
}
function c(): StringMap {
var result = { a: "1" };
return result; // Error - result lacks index signature, why?
}
从TypeScript 1.8之后的任何版本开始(或者现在,如果你使用的是最前沿的编译器),当一个类型的原始表达式是一个对象文字时,你将不会再看到这个错误。
请参阅https://github.com/Microsoft/TypeScript/pull/7029
索引签名和对象文字在TypeScript中特别表现。 从规范4.5节,对象文字:
当对象文字由包含类型T的字符串索引签名的类型进行上下文类型化时,对象文字的结果类型包括字符串索引签名,其中扩展形式为最常见的T类型和声明的属性类型在对象文字中。
这是什么意思呢?
当表达式的上下文提示其类型可能是什么时,就会发生上下文类型。 例如,在此初始化中:
var x: number = y;
表达式y
获取上下文类型的number
因为它正在初始化该类型的值。 在这种情况下,没有什么特别的事情发生,但在其他情况下会发生更有趣的事情。
最有用的案例之一是功能:
// Error: string does not contain a function called 'ToUpper'
var x: (n: string) => void = (s) => console.log(s.ToUpper());
编译器是如何知道s
是字符串的? 如果您自己编写该函数表达式,则s
将是any
类型,并且不会发出任何错误。 但是因为函数是由x
的类型在上下文中键入的,所以参数s
获取了类型string
。 很有用!
索引签名指定对象按字符串或数字索引时的类型。 当然,这些签名是类型检查的一部分:
var x: { [n: string]: Car; };
var y: { [n: string]: Animal; };
x = y; // Error: Cars are not Animals, this is invalid
缺少索引签名也很重要:
var x: { [n: string]: Car; };
var y: { name: Car; };
x = y; // Error: y doesn't have an index signature that returns a Car
希望上述两个片段显然应该导致错误。 这导致我们......
假设对象没有索引签名的问题是您无法初始化具有索引签名的对象:
var c: Car;
// Error, or not?
var x: { [n: string]: Car } = { 'mine': c };
解决方案是,当对象文字由具有索引签名的类型进行上下文类型化时, 如果匹配 ,则将该索引签名添加到对象文本的类型中 。 例如:
var c: Car;
var a: Animal;
// OK
var x: { [n: string]: Car } = { 'mine': c };
// Not OK: Animal is not Car
var y: { [n: string]: Car } = { 'mine': a };
让我们看一下问题中的原始函数:
function a(): StringMap {
return { a: "1" }; // OK
}
好的 ,因为return
语句中的表达式是由函数的返回类型在上下文中键入的。 对象文字{a: "1"}
具有其唯一属性的字符串值,因此可以成功应用索引签名。
function b(): StringMap {
var result: StringMap = { a: "1" };
return result; // OK
}
好的 ,因为显式类型变量的初始化器是由变量类型的上下文类型。 和以前一样,索引签名被添加到对象文字的类型中。
function c(): StringMap {
var result = { a: "1" };
return result; // Error - result lacks index signature, why?
}
不行 ,因为result
的类型没有索引签名。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.