我们在基于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
类型的对象时阻止声明未定义的类型属性。
有人遇到过类似问题吗?
谢谢
正如@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抱怨错误。