通用功能允许任意键

时间:2017-08-24 17:54:32

标签: typescript

为什么以下代码编译成功?由于Assembly assembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(path); if (assembly == null) throw new InvalidExtensionException(name, path); TypeInfo type = assembly.DefinedTypes.FirstOrDefault(x => x.ImplementedInterfaces.Contains(typeof(IExtension))); if (type == null) throw new InvalidExtensionException(name, path); IExtension extension = Activator.CreateInstance(type.AsType(), name, _dependencyUtility) as IExtension; if (extension == null) throw new InvalidExtensionException(name, path); extensions.Add(extension); 不属于bar,我希望它会产生编译错误。

MyState

2 个答案:

答案 0 :(得分:5)

crashmstr的答案是正确的,但值得解释为什么这种情况与错误的情况不同。

对象文字只会在特定情况下导致额外的属性错误。

在这种情况下:

var x: MyState = { foo: 10, bar: 20 };

类型系统执行以下步骤:

  • 检查MyState是否为有效类型(确实如此)
  • 检查初始化程序是否有效:
    • 初始化程序的类型是什么?
      • 新鲜对象类型{foo: 10, bar: 20}
    • 可分配给MyState吗?
      • 是否有foo财产?
      • 它的类型是否匹配?
        • 是(10 - > number
      • 是否有来自新鲜类型的额外属性?
          • 错误

这里的关键是新鲜度。对象文字中的类型是 fresh ,如果它直接来自对象文字本身 。这意味着

之间存在差异
// Error
var x: MyState = { foo: 10, bar: 20 };

// OK
var x1 = { foo: 10, bar: 20 };
var x2: MyState = x1;

因为对象文字的 fresh 在分配到x1后消失了。

你的例子遭受同样的命运 - 一旦它成为函数返回类型的一部分,对象文字的新鲜度就消失了。这也解释了如果函数表达式上有返回类型注释,错误会重新出现的原因。

答案 1 :(得分:4)

TypeScript中的类型兼容性基于结构子类型。结构类型是一种仅根据其成员关联类型的方式。这与名义打字形成对比。

Type Compatibility

  

要检查是否可以将y分配给x,编译器会检查x的每个属性以在y中查找相应的兼容属性。在这种情况下,y必须有一个名为name的成员,它是一个字符串。它确实如此,因此允许分配。请注意,y具有额外的位置属性,但这不会产生错误。在检查兼容性时,仅考虑目标类型的成员(在本例中为命名)。

因此,在您的示例中,{ foo: 123, bar: 123 }符合要求foo为数字的要求,并且类型兼容性会忽略额外的bar

注意:另请参阅Why am I getting an error “Object literal may only specify known properties”?