TypeScript:没有明确返回类型的 lambda 表达式中不会检查多余的属性

IT技术 javascript reactjs typescript redux
2021-05-22 23:05:18

在下面的例子中,我试图弄清楚为什么我的输入适用于我的对象的所有部分,除了我的减速器返回类型?

如果我明确设置: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
})

2个回答

最后我在 GitHub 中找到了这个问题,正是关于这个问题的。简而言之:

理想情况下,这将是一个错误。不幸的是,事实证明很难解决这个问题而不可能对失控的递归和/或性能产生影响

原始答案: 从typescript 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

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

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