TypeScript:在没有显式返回类型的 lambda 中不检查多余的属性



在下面的示例中,我试图弄清楚为什么我的键入适用于除化简器返回类型之外的对象的所有部分?

如果我显式设置:reducer: (state, action): CounterState编译器抱怨(如预期的那样(我没有返回正确的状态。问题是,我不明白为什么我必须这样做,因为我已经在我的Config类型中强制执行了这一点??

简化的示例:

interface CounterState {
    counter: number;
}
type Reducer = () => CounterState
const reducer1: Reducer = () => ({
    counter: 1,
    foo: 'bar' // no errors, why?
})
const reducer2: Reducer = (): CounterState => ({
    counter: 1,
    foo: 'bar' // error: Object literal may only specify known properties
})
最后,

我在 GitHub 中找到了问题,正是关于问题。总之:

理想情况下,这将是一个错误。不幸的是,事实证明它非常 很难在不产生后果的情况下解决此问题 失控递归和/或性能

原答案:从打字稿 1.6 开始,对象文字不能有额外的属性。但是,如果将对象强制转换为类型,则允许使用额外的属性。例如:

const state: CounterState = {
    counter: 1,
    foo: "bar" // Error, unknown property 'foo'
};
const state2 = {
    counter: 1,
    foo: "bar" // no errors
} as CounterState

它看起来与您的问题非常相似,当您显式指定 lambda 返回类型时,将应用第一条规则。但是,如果未指定返回类型,编译器会认为:"好吧,也许我可以将对象强制转换为 CounterState...可以吗?我不确定。。。但是,我会努力的!",并应用了第二条规则。

但是我不能参考任何描述这种行为的文档或编译器规范,我也没有找到它。

TypeScript 中的类型兼容性基于结构子类型。

https://www.typescriptlang.org/docs/handbook/type-compatibility.html

打字稿旨在允许额外的属性。但是在某些地方,我们有一些不一致的行为,它声称object literal may only specify known properties .这种行为更令人期待,但它不是一个结构性的子类型......

https://medium.com/@KevinBGreene/surviving-the-typescript-ecosystem-interfaces-and-structural-typing-7fcecd54aef5

最新更新