仅在具有类型中定义的确切属性的常量中声明对象

问题描述 投票:1回答:1

我们在基于JS的应用程序中使用typescript和JSDoc,仅用于定义我们在函数中使用的参数类型。在特定情况下,我们希望具有定义结构的对象,并且我们需要确保在特定类型下声明的每个对象仅具有预期的属性

type Keys = 'foo' | 'bar';

type Things = {
  [K in Keys]: Thing;
}

interface Thing {
  a: string;
  b: string;
}

在创建Things类型的对象时,我希望这只有Thing中定义的属性

const object = /** @type {Things} */ ({
  foo: { a: 'foo_a', b: 'foo_b' },
  bar: { a: 'bar_a', b: 'bar_b' }
})

但实际上,我们可以在没有任何抱怨的情况下声明属性abc。如果在尝试访问该对象的属性时,我们只会调用类型声明中不存在的属性。例如,如果我们做object.abc它会抱怨。

错误

如您所想,这将触发错误:

object.abc // abc is not defined in type Things

没有错误

添加未在Type中定义的abc不会触发TS错误:

const object = /** @type {Things} */ ({
  foo: { a: 'foo_a', b: 'foo_b' },
  bar: { a: 'bar_a', b: 'bar_b' },
  abc: { a: 'abc_a', b: 'abc_b' },
})

我想在创建Things类型的对象时阻止声明未定义的类型属性。

操场

TypeScript playground example

有人遇到过类似问题吗?

谢谢

javascript typescript typescript-typings jsdoc
1个回答
0
投票

正如@ExplosionPills所说:

const object = /** @type {Things} */ ({
    foo: { a: 'foo_a', b: 'foo_b' },
    bar: { a: 'bar_a', b: 'bar_b' },
    abc: { a: 'abc_a', b: 'abc_b' } // This shouldn't be allowed. Not defined in Keys 
})

“object”未定义为“Things”类型,因此它不会出错,因为对象隐式为any类型,因此您可以为其分配任何内容。

您需要将代码更改为:

const object : Things = /** @type {Things} */ ({
    foo: { a: 'foo_a', b: 'foo_b' },
    bar: { a: 'bar_a', b: 'bar_b' },
    abc: { a: 'abc_a', b: 'abc_b' } // This will now be highlighted as an error 
})

只有这样才允许将类型为Things的对象分配给对象。完成此更改后,您将看到Typescript抱怨错误。

© www.soinside.com 2019 - 2024. All rights reserved.