我试图定义一个具有返回类型(对象)的函数类型,以强制实现它的函数返回返回类型中定义的确切对象属性。
但是,编译器对返回的对象并不严格,并且允许返回的对象类型中未定义的额外属性。
interface Obj {
foo: string;
}
type Func = () => Obj;
const fn: Func = () => {
return {
foo: 'bar',
blah: '', // compiler does not show an error
};
};
Run Code Online (Sandbox Code Playgroud)
相反,如果Obj在函数中指定了返回类型fn,则编译器会显示错误。
interface Obj {
foo: string;
}
const fn = (): Obj => {
return {
foo: 'bar',
blah: '', // compiler shows an error
};
};
Run Code Online (Sandbox Code Playgroud)
有人可以解释为什么 TS 以不同的方式处理这些情况吗?有没有办法在使用函数类型时保证返回类型的严格性?
在第一个示例中,匿名函数的返回类型动态定义如下{ foo: string; blah: string; }:此类型与类型兼容Obj,因为它具有 (以及更多) 的所有必需属性Obj,但这足以被视为兼容,因为“结构类型是仅基于其成员来关联类型的一种方式”,来自https://www .typescriptlang.org/docs/handbook/type-compatibility.html)。
最后,该Func类型与匿名函数的静默定义类型兼容() => { foo: string; blah: string; },因此发生“隐式转换”并进行编译。
在第二个示例中,签名强制匿名函数本身的返回类型,因此返回的对象是一个应该完全属于 类型的文字Obj。因此,出于同样的原因,您不能执行:let obj: Obj = { foo:'bar', blah:'' },此代码无法编译,因为在这种情况下没有兼容性检查,因为它的类型是显式定义的。
干杯!