TypeScript: excess properties are not checked in lambdas without explicit return type
在下面的示例中,我试图弄清楚为什么我的键入除了我的reducer返回类型之外还可以用于对象的所有部分?
如果我明确设置:
简化示例:
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设计为允许额外的属性。但是在某些地方,我们的行为有些不一致,它声明为
https://medium.com/@KevinBGreene/surviving-the-typescript-ecosystem-interfaces-and-structural-typing-7fcecd54aef5