关于javascript:TypeScript:如果没有明确的返回类型,则不会在lambda中检查多余的属性

TypeScript: excess properties are not checked in lambdas without explicit return type

在下面的示例中,我试图弄清楚为什么我的键入除了我的reducer返回类型之外还可以用于对象的所有部分?

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

简化示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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上找到了与该问题有关的问题。简而言之:

Ideally this would be an error. Unfortunately it turns out to be very
difficult to fix this without possibly having consequences in terms of
runaway recursion and/or performance

原始答案:
从typescript1.6开始,对象文字不得具有额外的属性。但是,如果将对象强制转换为类型,则可以使用额外的属性。例如:

1
2
3
4
5
6
7
8
9
const state: CounterState = {
    counter: 1,
    foo:"bar" // Error, unknown property 'foo'
};

const state2 = {
    counter: 1,
    foo:"bar" // no errors
} as CounterState

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

但是我无法参考描述此类行为的任何文档或编译器规范,我也没有找到它。


Type compatibility in TypeScript is based on structural subtyping.

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