为什么以下代码编译成功?由于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
答案 0 :(得分:5)
crashmstr的答案是正确的,但值得解释为什么这种情况与做错误的情况不同。
对象文字只会在特定情况下导致额外的属性错误。
在这种情况下:
var x: MyState = { foo: 10, bar: 20 };
类型系统执行以下步骤:
{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中的类型兼容性基于结构子类型。结构类型是一种仅根据其成员关联类型的方式。这与名义打字形成对比。
要检查是否可以将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”?