Typescript 在用对象解析 promise 时允许冗余键

Typescript allows redundant keys when resolving promise with object

你能帮我理解为什么 Typescript 不会在这里抛出错误吗:

type Test = Promise<{a: number}>;
const test: Test = Promise.resolve({a: 1, something: 'wrong'}); // no error

但在这里

type Test2 = {a: number};
const test2: Test2 = {a: 1, something: 'wrong'}; // error 2322, ok

我能做些什么来让它抛出与 Promise 类似的错误吗?

在 Typescript 的不同版本上尝试过,包括最新版本,具有严格的类型。 尝试使用 new Promise 而不是 Promise.resolve。没有任何帮助。 看看 Playground

提前致谢!

TypeScript 仅在非常有限的情况下进行额外的 属性 检查(直接将对象文字赋值给类型化变量,从函数返回对象文字;details here),因为尽管来自类型系统那些额外的属性很好(它们只是意味着实例是具有更多信息的类型的子类型),将它们放在您要分配的对象文字上通常是程序员的错误。它不会以其他方式进行检查,因为在一般情况下,它很可能不是错误(再次只是一个子类型)。

您可以通过向 Promise.resolve 提供类型参数来触发对 属性 的额外 属性 检查 (playground link) (thanks jcalz!):

const test = Promise.resolve<{a: number}>({a: 1, something: 'wrong'});
//                                               ^^^^^^^^^^^^^^^^^^−− Argument of type '{ a: number; something: string; }' is not assignable to parameter of type '{ a: number; } | PromiseLike<{ a: number; }>'

在那里,TypeScript 会将 test 的类型推断为 Promise<{a: number}>(例如,您的 Test 类型)。

您还可以检查 async 函数 returns (playground link):

type Test = Promise<{a: number}>;
async function asyncExample(a: number): Test {
    return {a, extra: true}; // Type '{ a: number; extra: boolean; }' is not assignable to type '{ a: number; }'
}

...因此,如果您可以使用 async 函数而不是显式的 promise 语法,您可能能够加强检查。