对象文本'is not assignable to parameter of type'错误



对象文字类型有问题。

interface OptionalFoo {
foo?: number;
}
interface Bar {}
function foobarFn(foobar: OptionalFoo & Bar) {}
foobarFn({ bar: 1 }); // error
foobarFn({ bar: 1 } as { bar: number }); // ok
foobarFn({ bar: 1 } as { bar: 1 }); // ok!

具有推断类型的对象文字导致类型错误:

类型为"{bar:number;}"的参数不可分配给类型为"OptionalFoo&条形

但问题不在于推理本身:

const bar = { bar: 1 }; // inferred { bar: number; }
foobarFn(bar); // ok!?

排列语法与Object.assign:的问题相同

foobarFn({...{ bar: 1 }}); // error
foobarFn(Object.assign({}, { bar: 1 })); // ok!?

有没有一种方法可以在没有对象文本的情况下实现推断对象文本类型(过度属性检查(的行为,例如使用bar变量或类似Object.assign({ bar: 1 })的函数调用?

为了清楚起见,这不仅仅是关于过度的属性检查。当我们将对象文字直接分配给一个位置时,多余的属性检查就会发挥作用。在您的情况下,当间接分配对象时会发生更令人惊讶的行为,这通常是在过多的属性检查下允许的。

function foo(o: { bar: number }) { }
foo({ bar: 0, foo: "" }) // error direct assignment
foo({ bar:0, foo: ""} as { bar:0, foo: "" }) // ok indirect

至少对我来说,令人惊讶的是,另一个检查(弱类型检查(没有发现这个错误。在弱类型检查(如本文所述(下,如果一个类型只有可选属性,并且我们试图分配一个没有共同属性的类型,我们应该得到一个错误:

function foo(o: { bar?: number }) { }
foo({ foo: "" }) // error under excess properties:  Object literal may only specify known properties, and 'foo' does not exist in type
foo({ foo: ""} as { foo: "" }) // error under weak types: Type '{ foo: ""; }' has no properties in common with type '{ bar?: number; }'.

我认为这是弱类型检查中的一个漏洞(我不确定是否是设计错误(。弱类型是(根据本PR(:

  1. 至少具有一个属性的对象类型
  2. 其中所有属性都是可选的
  3. 并且没有字符串索引签名、数字索引签名、调用签名或构造签名

但是,在交叉口的弱类型检查的实现中,交叉口的所有类型都必须是弱类型,交叉口才能是弱类型。来自编译器代码(添加注释(:

function isWeakType(type: Type): boolean {
if (type.flags & TypeFlags.Object) {
// ....
}
if (type.flags & TypeFlags.Intersection) {
/// All intersection members have to be weak
return every((<IntersectionType>type).types, isWeakType); 
}
return false;
}

由于interface Bar {}不是弱类型(根据第一条规则,它没有属性(,与它的任何交集都不会是弱类型,也不会引发任何弱类型检查错误。从交集中删除Bar会在指定与目标没有任何共同点的对象时到处抛出错误。

相关内容

最新更新