当我内联函数的返回值类型以及如果我在单独的类型定义中对其进行定义时,我会出现不一致的行为。
例如:
interface Foo {
bar: string;
}
type Fooer = () => Foo;
const foo1: Fooer = () => { // It knows `.bar` should be a string
return {
bar: 123,
};
}
// Return type set in a separate type definition
const foo2: Fooer = () => {
return {
foo: 123, // It doesn't complain about additional properties
bar: "zzz",
};
}
// Inline (repeated) return type
const foo3: Fooer = (): Foo => {
return {
foo: 123, // And now it does...
bar: "zzz",
};
}
Try it on the TypeScript Playground
我希望foo2
和foo3
的行为相同(就个人而言,我希望两者都显示相同的错误,或者至少是一致的)。
我在这里想念什么?两种方法有什么区别?
答案 0 :(得分:2)
这里发生的是TypeScript的“鸭子打字”的结果。基本上,foo2中的返回类型具有一个字符串形式的bar
字段这一事实意味着该函数具有一个签名() => Promise<{foo: number, bar: string}>
,可以将其分配给类型{的foo2
变量{1}}是由于鸭子打字造成的。
但是,在foo3中,您可以认为类型检查直接应用于返回类型,而不是整个函数。结果,您会看到错误Fooer
,因为类型检查是在对象文字上执行的,它还具有附加要求,即在给它提供显式类型时不能指定未知属性。
答案 1 :(得分:2)
这与TypeScript处理类型文字的方式有关,而与函数是否异步无关—如果它们是常规函数,其行为将是相同的。
通常,TypeScript允许对象中存在多余的属性。如果对象具有其所有必需的属性,则其余的无所谓。几乎是您发现的例外:键入文字和显式定义的返回类型。